一、左旋字符串
例如字符串 abcd ,左旋一个就是 bcda ,左旋两个就是 cdab 。
方法一:循环
#include <stdio.h>
#include <string.h>
void func(char* str, int n)
{
int i = 0;
int j = 0;
int len = (int)strlen(str);
n %= len;//超出字符串长度的次数就不用再左旋,左旋len次就相当于字符串没变
for (i = 0; i < n; i++)
{
char c = *str;
for (j = 0; j < len - 1; j++)
{
str[j] = str[j + 1];
}
str[len - 1] = c;
}
}
int main()
{
char str[] = "abcd";
func(str,2);
printf("%s\n", str);
return 0;
}
用n控制左旋次数,用c作为临时变量存储第一个字符,然后将字符串整体向左移一个元素大小,然后将临时变量存储的字符放到最后。
运行结果:
方法二:递归
#include <stdio.h>
#include <string.h>
void func(char* str, int n)
{
char c = *str;
int len = (int)strlen(str);
n %= len;
int i = 0;
for(i = 0;i < len - 1;i++)
{
*(str + i) = *(str + i + 1);
}
*(str + len - 1) = c;
if (n > 1)
{
func(str, n - 1);
}
}
int main()
{
char str[] = "abcd";
func(str,2);
printf("%s\n", str);
return 0;
}
与循环相似,这里使用n控制递归深度。
运行结果:
方法三:三次逆序
通过需要左旋的个数,将字符串分为两步分,分别对两部分进行逆序,然后在对整个字符串进行逆序,经过三次逆序就完成了对字符串的左旋。
#include <stdio.h>
#include <string.h>
void reverse(char* left, char* right)
{
char tmp = 0;
while (left < right)
{
tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
void func(char* str, int n)
{
int len = (int)strlen(str);
n %= len;
reverse(str, str + n - 1);
reverse(str + n, str + len - 1);
reverse(str, str + len - 1);
}
int main()
{
char str[] = "abcdef";
func(str,2);
printf("%s\n", str);
return 0;
}
运行结果:
二、判断一个字符串可不可以通过另一个字符串左旋得到
方法一:穷举
#include <stdio.h>
#include <string.h>
int foo(char* string1, char* string2)
{
int len = (int)strlen(string1);
int i = 0,j = 0;
char tmp = 0;
for (i = 0; i < len; i++)
{
tmp = string1[0];
for (j = 0; j < len - 1; j++)
{
string1[j] = string1[j + 1];
}
string1[j] = tmp;
if (strcmp(string1, string2) == 0)
{
return 1;
}
}
return 0;
}
int main()
{
char str1[] = "abcd";
char str2[] = "abcd";
if (foo(str1, str2))
{
printf("yes\n");
}
else
{
printf("no\n");
}
return 0;
}
将第一个字符串一次一次左旋,然后与第二个字符串比较,字符串左旋自己的长度次就变回了原样,所以只用循环 len 次。
运行结果:
方法二、库函数
当我们使用 strcat 库函数在第一个字符串的后面再追加一个第一个字符串,我们就能发现我们可以在这个字符串中找到所有自旋的情况。
这样我们就可以使用 strstr 库函数来找第二个字符串是否在这个字符串中存在了。
这种方法要在函数里判断两个字符串长度是否相等,以防第二个字符串大于或小于第一个字符串,而且是第一个字符串追加后的字符串的子字符串。
而且 string1 还要有足够的空间以供后续追加。
#include <stdio.h>
#include <string.h>
int foo(char* string1, char* string2)
{
if (strlen(string1) != strlen(string2))
{
return 0;
}
int len = strlen(string1);
strncat(string1, string1,len);
if (strstr(string1, string2) != NULL)
{
return 1;
}
return 0;
}
int main()
{
char str1[20] = "abcd";
char str2[20] = "abcd";
if (foo(str1, str2))
{
printf("yes\n");
}
else
{
printf("no\n");
}
return 0;
}
运行结果: