读程序员编程艺术第一章---左旋字符串(二)
2014-03-16 20:05
483 查看
上一遍介绍了左旋字符串的第一种方法,暴力移位法。今天我们通过指针翻转法来实现左旋字符串。下面看一个例子。字符串“abcdefghijk”通过左移得到"defghijkabc"。我们可以通过两步来实现。首先定义两个指针p1,p2指向要交换的两个字符,如p1指向a,p2指向d,将p1与p2指向的字符进行交换,然后p1++,p2++。这样反复重复,知道p2指向末尾的字符。这样可以得到字符串defghijkcab。剩下的就是处理尾巴。此时我们可以知道p1指向c,p2指向b,将ab向左移动两个单位既可以得到的字符串。
下面是代码实现:
还有一种方法也可以实现:
当字符串变为defghiabcjk的时候,p1指向a,p2指向j。将jk移到abc之前即可。代码编写如下:
还有一种更为巧妙的方法就是通过递归翻转,逐步减小问题的规模。左右的回荡。如“abcdefghijk”首先进行左旋得到“defghiabcjk”,然后将尾部“abcjk”看做一个单独的问题进行右旋得到“ajkbc”。再将“ajk”看做一个更小的问题进行左旋。这样不断的左旋右旋,直到n%m=0时才停止,这样就解决了这个问题。代码编写如下:
下面是代码实现:
#include "stdafx.h" #include"string" #include"iostream" using namespace std; void rotate(string &str,int m) { //例如"abcdefghijk",其中n=11,m=3 //做简单的初始化工作 int n=str.length(); int p1=0; int p2=m; //p2指到最后,操作完之后变为defghijkcab while(true) { swap(str[p1],str[p2]); p1++; if(p2<n-1) { p2++; } else { break; } } //现在处理尾巴,需要移动的位数为r int r=m-(n%m); while(r--) { int i=p1; char temp=str[i]; while(i<p2) { str[i]=str[i+1]; i++; } str[p2]=temp; } } int main() { string str="abcdefghijk"; cout<<str<<endl; rotate(str,str.length(),3); cout<<str<<endl; return 0; }
还有一种方法也可以实现:
当字符串变为defghiabcjk的时候,p1指向a,p2指向j。将jk移到abc之前即可。代码编写如下:
#include "stdafx.h" #include"string" #include"iostream" using namespace std; void rotate(string &str,int m) { //例如"abcdefghijk",其中n=11,m=3 //做简单的初始化工作 int n=str.length(); int p1=0; int p2=m; //计算可以交换的次数k int k=n-m-(n%m); //操作之后为defghiabcjk for(int i=1;i<=k;i++) { swap(str[p1],str[p2]); p1++; p2++; } //需要交换的位数r int r=n-p2; while(r--) { int i=p2; while(i>p1) { swap(str[i],str[i-1]); i--; } p1++; p2++; } } int main() { string str="abcdefghijk"; cout<<str<<endl; rotate(str,3); cout<<str<<endl; return 0; }
还有一种更为巧妙的方法就是通过递归翻转,逐步减小问题的规模。左右的回荡。如“abcdefghijk”首先进行左旋得到“defghiabcjk”,然后将尾部“abcjk”看做一个单独的问题进行右旋得到“ajkbc”。再将“ajk”看做一个更小的问题进行左旋。这样不断的左旋右旋,直到n%m=0时才停止,这样就解决了这个问题。代码编写如下:
#include "stdafx.h" #include"string" #include"iostream" using namespace std; //通过递归来实现左移字符串 //"abcdefghijk"通过简单的左移之后"defghiabcjk", //现在可以考虑将"abcjk"中的jk右旋得到"ajkbc", //现在相当于将"ajk"左旋得到"jka"结束。 void rotate(string &str,int n,int m,int head,int tail,bool flag) { //flag为true表示左旋,head表示起始字符位置,tail表示结束字符位置 if(head==tail) return; if(flag==true) { //初始化操作 int p1=head; int p2=head+m; //可以右移的位数 int k=n-m-(n%m); for(int i=0;i<k;i++) { swap(str[p1],str[p2]); p1++; p2++; } //将剩下的部分做右旋操作,其中的长度为n-k,右旋位数为n%m,起始字符为现在的p1,结束位置为tail rotate(str,n-k,n%m,p1,tail,false); } else { //初始化操作 int p1=tail; int p2=tail-m; int k=n-m-(n%m); for(int i=0;i<k;i++) { swap(str[p1],str[p2]); p1--; p2--; } //将剩下的部分做左旋操作 rotate(str,n-k,n%m,head,p1,true); } } int main() { string str="abcdefghijk"; cout<<str<<endl; rotate(str,str.length(),3,0,str.length()-1,true); cout<<str<<endl; return 0; }
相关文章推荐
- 读程序员编程艺术第一章---左旋字符串(三)
- 读程序员编程艺术第一章---左旋字符串
- 程序员编程艺术(算法卷):第一章、左旋转字符串
- 【程序员编程艺术】第一章:左旋转字符串
- 程序员编程艺术_第一章左旋转字符串_C实现
- 算法题002 程序员编程艺术第一章 左旋转字符串
- 程序员编程艺术(算法卷):第一章、左旋转字符串
- 程序员编程艺术(算法卷):第一章、左旋转字符串
- 程序员编程艺术:第一章、左旋转字符串
- 程序员编程艺术(算法卷):第一章、左旋转字符串
- 程序员编程艺术:第一章、左旋转字符串
- 程序员编程艺术(算法卷):第一章、左旋转字符串
- 程序员编程艺术(算法卷):第一章、左旋转字符串探讨
- 程序员编程艺术(算法卷):第一章、左旋转字符串
- 程序员编程艺术第一章、左旋转字符串
- 程序员编程艺术第一章、左旋转字符串
- 程序员编程艺术第一章、左旋转字符串
- 程序员编程艺术第一章、左旋转字符串
- 程序员编程艺术:第一章、左旋转字符串
- 程序员编程艺术学习笔记(一)字符串左旋问题