字符串左旋问题

问题描述

实现一个函数,可以左旋字符串中的k个字符。例如 ABCD左旋一个字符得到BCDA ,ABCD左旋两个字符得到CDAB

解法一:暴力移位法

  • 假设将ABCDE左旋转一个字符得到的是BCDEA
  • 首先将A储存起来
  • 找到’\0’循环结束,避免将’\0’移动
  • 然后BCDE逐个向左移动
    这里写图片描述

参考代码:


    #include<stdio.h>
    #include<windows.h>
    #include<assert.h>

    void left_swap(char *str, int n)
    {
        assert(str != NULL);
        while (n--)
        {
            char *cur = str;
            char temp = *cur;
            //将第一个元素储存在temp中
            while (*(cur + 1) != '\0')
            {
                *cur = *(cur + 1);
                //逐个左移
                cur++;
            }
            *cur = temp;
            //将之前储存起来的元素放在最后
        }
    }
    int main()
    {
        char arr[] = "ABCDE";
        int num = 0;
        printf("请输入要旋转的个数:");
        scanf_s("%d", &num);
        left_swap(arr, num);
        printf("%s\n", arr);
        system("pause");
        return 0;
    }

解法二:三步翻转法

  • 假设将ABCDE左旋转两个字符得到的是CDEAB
  • 首先翻转要旋转的字符ABCDE——>BACDE
  • 然后翻转不旋转的字符BACDE——>BAEDC
  • 最后翻转整个字符串BAEDC——>CDEAB
    这里写图片描述

参考代码:


    #include<stdio.h>
    #include<windows.h>
    #include<assert.h>

    static 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_swap(char *str, int n)
    {
        reverse(str, str + n - 1);
        reverse(str+n, str+strlen(str)-1);
        reverse(str, str + strlen(str) - 1);
        //传入三步的首位地址
    }

    int main()
    {
        char arr[] = "ABCDE";
        int num = 0;
        printf("请输入要旋转的个数:");
        scanf_s("%d", &num);
        left_swap(arr, num);
        printf("%s\n", arr);
        system("pause");
        return 0;
    }

推广:判断一个字符串是不是经过另一个字符串旋转的到的

  • 假设判断BACDE是不是字符串ABCDE旋转得到的
  • 首先,拼接字符串ABCDE自身得到字符串ABCDEABCDE
  • 可以发现如果BACDE是字符串ABCDE旋转得到的,就一定是字符串ABCDEABCDE的子串
  • 由库函数strstr判断BACDE是不是字符串ABCDEABCDE的子串

参考代码:

    #include<stdio.h>
    #include<windows.h>
    #include<assert.h>
    #include<string.h>

    int is_swap(char *sour, const char* cmp)
    {
        assert(sour != NULL);
        assert(cmp != NULL);
        strncat(sour, sour, strlen(sour));
        //拼接自身字符串
        if (strstr(sour, cmp) != NULL)//判断是否为子串
        {
            return 1;
        }
        return 0;
        //返回1表示是,返回0表示不是
    }

    int main()
    {
        char sour[20] = "ABCDEF";
        char *cmp = "CDEFAB";
        int ret=is_swap(sour, cmp);
        if (1 == ret)
        {
            printf("是\n");
        }
        else
        {
            printf("不是\n");
        }
        system("pause");
        return 0;
    }

在上边的代码连接字符串用了strncat函数,为什么不用strcat函数呢?

strcat(str,str)会引起死循环,因为strcat函数要先找到第一个字符串的’\0’,找到之后从’\0’开始追加字符串,把第一个字符拷贝过去之后’\0’已经被覆盖了,所以会引起死循环。

猜你喜欢

转载自blog.csdn.net/hansionz/article/details/80871953
今日推荐