字符串循环移位

题目示例: "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 }