左旋字符串中的k个字符
例如:
abcdef左旋一个字符得到bcdefa;
abcdef左旋两个字符得到cdefab;
int main()
{
char arr[] = "abcdef";//注意此处不可将字符串设置成常量字符串形式,否则将无法更改字符串内容
left_move(arr, 5);
printf("%s\n", arr);
return 0;
}
建立一个left_move函数来实现左旋的过程,其中需要两个参数,一是所需左旋字符串的地址,二是所需左旋几个字符。
一.暴力求解法
将第一个字符存储到中间变量中,然后将之后的字符依次向前移动一位,再将中间变量的值赋予给最后一位,进行循环,循环条件即为 < k。
void left_move(char* arr, int k)
{
assert(arr != NULL);
int len = strlen(arr);
for (int i = 0; i < k; i++)
{
//左旋转一个字符
//1.将首元素存贮到中间变量中
char tmp = *arr;
//2.将其后每一个字符向前移动一位
for (int j = 0; j < len - 1; j++)
{
*(arr + j) = *(arr + j + 1);
}
//3.将tmp的值赋予最后一位
*(arr + len - 1) = tmp;
}
}
二.三步翻转法
第一步:将字符串分为两部分,第一部分为即将左旋的字符,第二部分为不左旋的字符
第二步:分别将两部分字符进行逆序
第三步:将得到的新字符串整体进行逆序
例如:
将abcdef左旋两个字符
1.分为ab和cdef两部分
2.将ab逆序为ba,将cdef逆序为fedc
3.bafedc逆序为cdefba即为结果
所以运用这种方法时,要创建一个新函数reverse,它需要两个参数,一个是逆序的起始位置,另一个为逆序的终止位置.
void reverse(char* left, char* right)
{
assert(left != NULL);
assert(right != NULL);
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
void left_move(char* arr, int k)
{
assert(arr);
int len = strlen(arr);
assert(k <= len);
reverse(arr, arr + k - 1);//逆序左边
reverse(arr + k, arr + len - 1);//逆序右边
reverse(arr, arr + len - 1);//逆序整体
}