• 字符串循环移位


    题目示例: "abcdefgh" 循环右移3位得到 "defghabc"

    解法一:消耗额外的3个空间,空间复杂度为O(n),当程序运行的空间比较苛刻的时候,不可取。时间复杂度为O(n)

    1 int main(){
    2     char source[]="abcdefg";
    3     char *temp=new char[3];
    4     int i;
    5     for(i=0;i<3;i++)temp[i]=source[i];
    6     for(i=0;i<(strlen(source)-3);i++)source[i]=source[i+3];
    7     for(i=0;i<3;i++)source[strlen(source)-3+i]=temp[i];
    8     cout<<source<<endl;
    9 }

    解法二:将每个元素直接移动到最后移动完字符串的相应的位置,所以需要移动n次。首先从x[0]开始,然后移动想想x[m]到x[0],x[2m]到x[i],依此类推,直到返回取x[0],如果从x[0]开始,没有能够移动所有元素,就从x[1]继续移动,直到所有元素都移动完为止。该算法的时间复杂度取决于外层循环执行的次数,当n,m的最大公倍数为1,则外层循环执行一次,如果最大公倍数为k,则执行k次。所以其时间复杂度几乎也为O(n)。解法2的空间复杂度较低,只占用一个字符的额外空间,为O(1)。

     1 int main(){
     2     char source[]="abcdef";
     3     int n=strlen(source);
     4     int m;cin>>m;//m为循环右移位数
     5     m=m%n;
     6     if(m==0)return 1;
     7     
     8     int start_pos=0;
     9     int changecount=0;
    10     
    11     while(changecount<n){
    12         char temp=source[start_pos];
    13         int cur_pos=start_pos;
    14         int next_pos=(cur_pos+m)%n;
    15         while(next_pos!=start_pos){
    16             source[cur_pos]=source[next_pos];
    17             changecount++;
    18             cur_pos=next_pos;
    19             next_pos=(cur_pos+m)%n;
    20         }
    21         source[cur_pos]=temp;
    22         changecount++;
    23         start_pos++;
    24     }
    25     cout<<source<<endl;
    26 }

    解法三:观察移位后的字符串和原串的差别,字符串移n位相当于把前n位挪到了后面,而把后n位移到前面。设字符串长为AB,完成移位操作后新串为BA,用A'表示A的反序串,B'表示B的反序串,那么 BA = B''A'' =(A'B')'。 

     1 void reverse(char *a,int start,int end){
     2     while(start<end){
     3         int temp=a[start];
     4         a[start]=a[end];
     5         a[end]=temp;
     6         start++;
     7         end--;
     8     }
     9 }
    10 
    11 int main(){
    12     char source[]="abcdef";
    13     int n=strlen(source);
    14     int m;cin>>m;//m为循环右移位数
    15     m=m%n;
    16     if(m==0)return 1;
    17 
    18     reverse(source,0,m-1);
    19     reverse(source,m,n-1);
    20     reverse(source,0,n-1);
    21     cout<<source<<endl;        
    22 }

    解法四:比较巧妙的做法就是对于字符串s,使newstring=ss,循环移n位的结果就等于newstring从下标n取strlen(s)位。如下题:

     1 int main(){
     2     vector<string> vec;
     3     int n;cin>>n;
     4     string s;
     5     for(int i=0;i<n*2;i++){cin>>s;vec.push_back(s);}
     6     int j=1;
     7     for(int i=1;i<vec.size();i=i+2){
     8         string temp=vec[i-1]+vec[i-1];
     9         int pos=temp.find(vec[i],0);
    10         if(pos>3)cout<<"Case "<<j<<": "<<(3-pos)<<endl;
    11         else
    12             cout<<"Case "<<j<<": "<<pos<<endl;
    13         j++;
    14     }
    15 
    16 }
  • 相关阅读:
    (转)WCF中的REST是什么
    DrpList
    IIS代码管理(1):遍历应用程序池和属性
    rdp,ListBox,Drp
    在.NET中杀死Word,Excel等进程
    IIS代码管理(2):创建应用程序池和属性
    防止用户重复登录
    asp.net2.0的几种自动生成脚本的原理以及应用
    工厂模式new问题
    我们需要什么样的字段类型?
  • 原文地址:https://www.cnblogs.com/irun/p/4526444.html
Copyright © 2020-2023  润新知