字符串左旋的两种思路与代码实现

题目描述

可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB


1. 第一种思路是把第一个字符存起来,比如“ABCD” ,先把‘A’字符存起来,再让后面的字符依次往前移动一位,再把第一个字符存放到最后一个位置既可完成,旋转k次只需要循环k次即可。

代码:

#include 
#include 

void left_rotate(char * str , int k) {
    assert(str != NULL);
    int i = 0;
    for (i = 0; i < k; i++) {
        // 保存第一个字符
        char temp = str[0];
        // 把后面的字符依次往前移动一位
        int j = 1;
        while (str[j]) {
            str[j - 1] = str[j];
            j++;
        }
        str[j - 1] = temp;
    }
}

int main() {

    char str[] = "ABCD";
    left_rotate(str , 6);
    puts(str);

    return 0;
}

第一种优化版:

优化具体思路是:比如“ABCD”这个字符串,左旋两个字符是“CDAB” ,如果左旋6次也是”CDAB“,其实左旋2次和左旋6次是等价的,因为字符串长度是4,当左旋4次的时候又旋转回来了还是原串,所以左旋2次和左旋6次是等价的。

#include 
#include 
#include 

void left_rotate(char * str , int k) {
    assert(str != NULL);
    int i = 0;
    int length = strlen(str);
    int count = 0;
    /*
		比如 字符串是 ”ABCD“
			没有优化的话:k是6的情况下 循环就会走6次
			优化后:k是6的情况下,当 k % 这个字符串的长度  6 % 4 = 2 只循环了2次	
	*/
    for (i = 0; i < k % length; i++) {
        // 保存第一个字符
        char temp = str[0];
        // 把后面的字符依次往前移动一位
        int j = 1;
        while (str[j]) {
            str[j - 1] = str[j];
            j++;
        }
        str[j - 1] = temp;
        count++;
    }
    printf("%d\n" , count); // 2
}

int main() {

    char str[] = "ABCD";
    left_rotate(str , 6);
    puts(str);

    return 0;
}

原来正常情况下会循环6次,经过优化只循环了2次。


2. 更优思路:比如字符串是”ABCDEF“,如果左旋2次的结果是”CDEFAB“。
我们可以用到字符串逆置的思想,如果左旋2个字符,我们可以让前2个字符逆置,后面剩余的字符也逆置,最后把整个字符串也逆置。
"ABCDEF" -> 前两个逆置和剩余的字符逆置 -> "BAFEDC -> 整体逆置 -> "CDEFAB" 也能得到最后的结果,但是这种方法不易于想到。非常巧妙。

代码:

#include 
#include 
#include 

// 逆置字符串
void reverse(char * str , int left , int right) {
    assert(str != NULL);
    while (left < right) {
        char temp = str[left];
        str[left] = str[right];
        str[right] = temp;
        left++;
        right--;
    }
}

void left_rotate(char* str, int k) {
    assert(str != NULL);
    int length = strlen(str);
    // 这一步为了防止k过大 导致下面逆置越界访问
    k %= length;
    // 逆置前k个字符
    reverse(str , 0 , k - 1);
    // 逆置剩余字符
    reverse(str , k , length - 1);
    // 整体逆置
    reverse(str , 0 , length - 1);
}

int main() {

    char str[] = "ABCDEF";
    left_rotate(str, 8);
    puts(str);

    return 0;
}

你可能感兴趣的:(c语言,学习,开发语言,字符串逆置,字符串左旋)