zoukankan      html  css  js  c++  java
  • 字符串旋转

    描述:

      给定一个字符串,要求把字符串前面若干个字符移位到字符串的尾部。

    思路与代码:

     1 //暴力法
     2 #include<stdio.h>
     3 #include<string.h>
     4 
     5 const int MAXN = 1e5;
     6 void move_one(char *s, int n)    //移动一个字符到尾部
     7 {
     8     char t = s[0];    //保存第一个字符
     9     for(int i = 1; i < n; i++)
    10     {
    11         s[i - 1] = s[i];
    12     }
    13     s[n - 1] = t;
    14 }
    15 void move(char *s, int n, int m)    //移动前m个字符到尾部
    16 {
    17     while(m--)
    18     {
    19         move_one(s, n);
    20     }
    21 }
    22 int main()
    23 {
    24     char str[MAXN];
    25     int m;
    26     while(scanf("%s", str) != EOF)
    27     {
    28         getchar();
    29         scanf("%d", &m);
    30         int len = strlen(str);
    31         move(str, len, m);
    32         for(int i = 0; i < len; i++)
    33             printf("%c", str[i]);
    34         printf("
    ");
    35     }
    36     return 0;
    37 }

    暴力法的复杂度:
      对一个长度为n的字符串来说,若需要移动m个字符到尾部,时间复杂度为O(m*n),空间复杂度为O(1),接下来来找找其他更好的方法来降低时间复杂度。

      举个例子,对于一个字符串abcdef,要将前三个移到尾部,可以先将原字符串划分成两部分,分别为字符串X:abc和字符串Y:def,然后将X反转变为cba,将Y反转变为fed,再将反转后的两字符串连接成cbafed,最后将连接后的再次反转即为defabc,得到移位后的字符串。所以找到了一种更高效的算法,将原字符串分成X和Y两部分,定义X^T为将字符串反转操作,则有(X^TY^T)^T=YX

     1 //三步反转法
     2 #include<stdio.h>
     3 #include<string.h>
     4 
     5 const int MAXN = 1e5;
     6 void reverse(char *s, int left, int right)  //反转字符串
     7 {
     8     while(left < right)
     9     {
    10         char t = s[left];
    11         s[left++] = s[right];
    12         s[right--] = t;
    13     }
    14 }
    15 void move(char *s, int n, int m)
    16 {
    17     m %= n; //若移动个数大于原长度,则和取余结果相等
    18     reverse(s, 0, m - 1);   //前部分[0,...,m-1]
    19     reverse(s, m, n - 1);   //后部分[m,...,n-1]
    20     reverse(s, 0, n - 1);   //再整体反转
    21 }
    22 int main()
    23 {
    24     char str[MAXN];
    25     int m;
    26     while(scanf("%s", str) != EOF)
    27     {
    28         getchar();
    29         scanf("%d", &m);
    30         int len = strlen(str);
    31         move(str, len, m);
    32         for(int i = 0; i < len; i++)
    33             printf("%c", str[i]);
    34         printf("
    ");
    35     }
    36     return 0;
    37 }

    三步反转法的复杂度:
      时间复杂度O(n),空间复杂度O(1)

  • 相关阅读:
    Proguard打包混淆报错:can't find superclass or interface
    proguard returned with error code 1.异常的解决方法
    android 混淆配置
    解决android混淆编译出现Proguard returned with error code 1和文件名、目录名或卷标语法不正确错误
    Eclipse提示No java virtual machine
    [mysql]数据库查询实例
    [算法]高效求素数
    [笔试]程序员面试宝典
    [linux]进程间通信IPC
    [linux]信号的捕获和处理
  • 原文地址:https://www.cnblogs.com/friend-A/p/9903252.html
Copyright © 2011-2022 走看看