左旋或右旋字符串的思路,例ABCDEF,左旋两位为CDEFAB

  1. 使用暴力旋转方法,例如左旋,即把第一个字符存放到临时变量中,再依次把后面的字符串往前挪动,最后把临时变量中存放的字符放到最后一个位置
【左旋或右旋字符串的思路,例ABCDEF,左旋两位为CDEFAB】void left_reverse(char* arr, int k)
{
int i = 0; int len = strlen(arr); for ( i = 0; i < k; i++)//控制左旋的次数 { char temp = *arr; //将数组首元素保存在临时变量中 int j = 0; for ( j = 0; j < len-1; j++)//依次挪动后面的元素,使其覆盖前一个元素 { *(arr + j) = *(arr + j + 1); } *(arr + len - 1) = temp; }

}
三步法,第一步,将需要左旋的字符整体逆序,第二步,将剩余的字符串整体逆序,第三部,将二者组合成的新字符串整体逆序即可
void reverse(char left, char right)//逆序函数,利用左右指针交换元素,左右指针从两端向中间移动
{
assert(left != NULL); assert(right != NULL); while (left < right) { char temp = *left; *left = *right; *right = temp; left++; right--; }

}
void left_reverse1(char* arr, int k)//实现三部逆序
{
assert(arr); int len = strlen(arr); reverse(arr, arr + k - 1); //先逆序前k个元素 reverse(arr + k, arr + len - 1); //逆序剩下的元素 reverse(arr, arr + len - 1); //将逆序完成的两部分合起来整体逆序即可

}
2. 比较一个字符串是否为另一个字符串左旋后的结果,目前有两种方法: a.暴力求解法:讲被比较的字符串依次旋转,把旋转的每种结果都和另外一个已经旋转的字符串比较int is_leftrverse(char* s1, char* s2) //传入进行比较的两个字符串 { int len = strlen(s1); int i = 0; for ( i = 0; i < len-1; i++)//将被比较的字符串逐一左旋 { left_reverse1(s1, 1); //为了保证字符串顺序不被破坏,所以每次只旋转一个 int ret = strcmp(s1, s2); //调用strcmp函数比较两个字符串是否相等 if (ret == 1) { return 1; //相等则返回1 } } return 0; //若旋转完所有字符串后仍然无法使二者相等,则返回0 }b.使用叠加法,例如,将ABCDEF扩充成ABCDEFABCDEF,若CDEFBA是扩充后的一个子串,则判断字符串2确实是字符串1旋转若干次数的结果,其中使用到库函数strncat()以及strstr();

int is_leftrverse1(char s1, char s2)
{
int len1 = strlen(s1); int len2 = strlen(s2); if (len1 != len2) { return 0; } strncat(s1, s1, len1); //给s1追加字符,例如使得abcdef变为abcdefabcdef char* ret = strstr(s1, s2); //判断s2指向的字符串是否是s1的子串 if (ret == NULL) { return 0; } else { return 1; }

}
*注释:为什么不用strcat函数,因为strcat函数的在追加字符串或数组时,末尾的/0会被覆盖掉。导致尾部追加的字符串在复制原字符串时无法复制/0,导致最终的字符串缺少/0,所以只能使用strncat函数
左旋或右旋字符串的思路,例ABCDEF,左旋两位为CDEFAB
文章图片

    推荐阅读