左旋或右旋字符串的思路,例ABCDEF,左旋两位为CDEFAB
- 使用暴力旋转方法,例如左旋,即把第一个字符存放到临时变量中,再依次把后面的字符串往前挪动,最后把临时变量中存放的字符放到最后一个位置
{
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函数
文章图片
推荐阅读
- 低头思故乡——只是因为睡不着
- 拒绝可以很艺术,或者很行为艺术。
- How|How Fear Works(PartⅡ)
- performSelectorOnMainThread:withObject:waitUntilDone:参数设置为NO或YES的区别
- 武功山金顶草甸或将易主(投资几千万开发,萍乡(有人想摘桃子))
- 狗趣
- 两个心得
- 插件化无法获取或找到.so文件
- 入以色列纪(四)
- 在树下