字符串的旋转
基本旋转
先从左旋讲起,所谓字符串左旋就是将左边的字符移到最右边,然后其余的字符向左移一位
例如: abcdefg 左移一次之后就变为 bcdefga
那么我们就能够依据此定义实现左移的代码:
void left_move(char *arr,int len)
{
char tmp = *arr;
for(int i=0;i<len-1;i++)
{
*(arr+i) = *(arr+i+1);
}
*(arr+i) = tmp;
}
那么如果是移动多次呢, 显然如果每一次都这么移动, 时间效率会比较低
一个算法
有一个实现的方法:
例如我们现在要左移三位
abcdefg --> defgabc
那么我们就将要移至末尾的和无需移至末尾的分为两部分
abc --> cba
defg --> gfed
分别进行逆序
然后合在一起之后再次进行逆序 即为结果
cbagfed --> defgabc
代码实现:
#include <stdio.h>
//指定范围进行逆序
void reverse(char* left,char *right)
{
while(left<right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
void left_move_k(char *arr,int len,int k)
{
k = k%len;
reverse(arr,arr+k-1);
reverse(arr+k,arr+len-1);
reverse(arr,arr+len-1);
}
int main()
{
char arr[] = "abcdefg";
left_move_k(arr,sizeof(arr)/sizeof(arr[0])-1,3);
printf("%s",arr);
return 0;
}
判断是否为某个字符串旋转得来
从0到len-1进行循环 每移动一次就比较一次 如果循环结束之后仍没有匹配的一次结果,那么不是该字符串旋转得来
还有更简单的一个方法 因为左旋旋转的次数如果很大 最终的结果其实也还是0~len-1的旋转 那么旋转的结果一定是比如 abcdefgabcdefg的子串 如果不是子串 那么就不会是该字符串旋转得来
bool is_move_result(char* origin,char* target,int len)
{
if((sizeof(target)-1)!=len)
{
return false;
}
char arr[len];
strcpy(arr,origin);
strcat(arr,origin);
return strstr(arr,target)!=NULL;
}
int main()
{
char arr[] = "abcdefg";
char target[] = "defgabc";
if(is_move_result(arr,target,sizeof(arr)-1)){
printf("是左旋得到的结果");
}
else{
printf("不是左旋得到的结果");
}
return 0;
}bool is_move_result(char* origin,char* target,int len)
{
if((sizeof(target)-1)!=len)
{
return false;
}
char arr[len];
strcpy(arr,origin);
strcat(arr,origin);
return strstr(arr,target)!=NULL;
}
int main()
{
char arr[] = "abcdefg";
char target[] = "defgabc";
if(is_move_result(arr,target,sizeof(arr)-1)){
printf("是左旋得到的结果");
}
else{
printf("不是左旋得到的结果");
}
return 0;
}