zoukankan      html  css  js  c++  java
  • 字符串循环移位

    题目示例: "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 }
  • 相关阅读:
    【转发】淘宝下单高并发解决方案
    ImageLoader的使用
    学习写接口回调
    EventBus的使用
    ListView显示多种类型的item
    GridView规则显示图片
    ViewPager滑动标签-PagerSlidingTabStrip的使用
    Json解析要点
    LISTVIEW嵌套GRIDVIEW的一些处理(点击GRIDVIEW的条目,能够显示他在LISTVIEW中的位置)(对这篇文章的优化处理,不每次都new onItemClickListener)
    SVN分支的创建,合并,与销毁和相关操作
  • 原文地址:https://www.cnblogs.com/irun/p/4526444.html
Copyright © 2011-2022 走看看