一道字符串翻转题
在网上看到了一道C语言的题,采用了三步翻转法实现
给定一个字符串,要求把字符串前面的若干个字符移动到字符串的尾部,如把字符串“abcde”前面的2个字符'a'和'b'移动到字符串的尾部,使得原字符串变成字符串“cdeab”。请写一个函数完成此功能,要求对长度为n的字符串操作的时间复杂度为 O(n),空间复杂度为 O(1)。
三步翻转法:
把一个字符串分成X,Y两部分,先把X部分翻转,再把Y部分翻转,最后再把XY一起翻转;比如"abcde"分成"ab","cde"两部分,"ab"部分翻转为"bc","cde"翻转为"edc"
两部分合在一起为"baedc"再翻转一次,变为"cdeab"。
void ReverseString(char* s,int from,int to)
{
while (from < to)
{
char t = s[from];
s[from++] = s[to];
s[to--] = t;
}
}
void LeftRotateString(char* s,int n,int m)
{
m %= n; //若要左移动大于n位,那么和%n 是等价的
ReverseString(s, 0, m - 1); //反转[0..m - 1],套用到上面举的例子中,就是X->X^T,即 abc->cba
ReverseString(s, m, n - 1); //反转[m..n - 1],例如Y->Y^T,即 def->fed
ReverseString(s, 0, n - 1); //反转[0..n - 1],即如整个反转,(X^TY^T)^T=YX,即 cbafed->defabc。
}
实际上,用js实现起来不需要用这个思路,直接用 sclie()
剪出来在拼接会方便很多。
var str = "abcde";
var str1 = str.slice(0, 2);
var str2 = str.slice(2);
var newStr = str2 + str1;
alert(newStr); //cdeab
但是因为心情好,还是照着写了 js 实现的版本
var string = "abcde"
function reverseString(str,from, to){
str = string;
splitStr = str.split("");
while(from < to){ //翻转
var temp = splitStr[from];
splitStr[from++] = splitStr[to]
splitStr[to--] = temp;
}
string = splitStr.toString();
string = string.replace(/,/g, ""); // 去掉字符串中的逗号
}
function leftRotateString(str, n ,m){ //字符串长度为n,要把m个字符移动到末尾
m %= n; //确保 m < n
reverseString(str, 0, m - 1); //套用在例子中就是 ab->ba
reverseString(str, m, n - 1); //cdef->fedc
reverseString(str, 0, n - 1); //cbafed->defabc。
return string;
}
alert(leftRotateString(string, 5, 2)) // "cdeab"
Comments