第一种方法为把右边的向左移,每次移动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