第一种方法为把右边的向左移,每次移动n位。一直到末尾,再把末尾的反转好
//字符串左移n位
void shift(std::string &str, int n)
{
int len = str.length();
if (len <= 0) return;
n = n%len;
int start = 0;//交换起始位置
int end = n;//后面交换的起始位置
int mark = end;//记录这个位置
while (true)
{
while (start != mark&&end < len)
{
char temp = str[start];
str[start] = str[end];
str[end] = temp;
++start;
++end;
//std::cout << str << std::endl;
}
if (start == mark)
{
if (end >= len)
return;
else
mark = end;//更新mark
}
else if (end >= len)
end = mark;
}
}//反转[start end]之间字符串
void inversion(std::string& str, int start, int end)
{
char temp;
while (start<end)
{
temp = str[start];
str[start] = str[end];
str[end] = temp;
++start;
--end;
}
}
void shift1(std::string& str, int n)
{
int len = str.length();
if (len <= 0) return;
n = n%len;
inversion(str, 0, n - 1);//反转前n半部分
inversion(str, n, len - 1);//反转后半部分
inversion(str, 0, len - 1);//整体反转
}
//计算公约数
int gcd(int max, int min)
{
if (min == 0)
return max;
return gcd(min, max%min);
}
void shift2(std::string& str, int n)
{
int len = str.length();
if (len <= 0) return;
n = n%len;
int GCD = gcd(len, n);
int loop = len / GCD;
for (int i = 0; i < GCD; ++i)//循环最大公约数次
{
char temp = str[i];
int j;
for (j = 0; j < loop - 1; ++j)//每次循环换loop个。
{
str[(i + j*n) % len] = str[(i + j*n + n) %len ];
}
str[(i + j*n) % len] = temp;
}
}int main()
{
std::string str = "abcde";
shift(str, 3);
std::cout << str << std::endl;
shift1(str, 3);
std::cout << str << std::endl;
shift2(str, 3);
std::cout << str << std::endl;
return 0;
}原文地址:http://blog.csdn.net/kangroger/article/details/40511729