程序员编程艺术第一章(第二节)

第二节:两指针逐步翻转

思路:
abc defghi,要 abc 移动至最后
abc defghi->def abcghi->def ghiabc
定义俩指针, p1 指向 ch[0], p2 指向 ch[m];
一下过程循环 m 次,交换 p1 和 p2 所指元素,然后 p1++, p2++;。


第一步,交换 abc 和 def ,
abc defghi->def abcghi


第二步,交换 abc 和 ghi,
def abcghi->def ghiabc


整个过程,看起来,就是 abc 一步一步 向后移动
abc defghi
def abcghi
def ghi abc


这个有个限制,如果字符串的个数正好是平移位的整数倍还好,如果不是 的话还要进行调整:

由上述例子九个元素的序列 abcdefghi,您已经看到, m=3 时, p2 恰好指到了数组最后
一个元素,于是,上述思路没有问题。 但如果上面例子中 i 的后面还有元素列?
即,如果是要左旋十个元素的序列: abcdefghij ok,下面,就举这个例子,对 abcdefghij
序列进行左旋转操作:
如果 abcdef ghij 要变成 defghij abc:
abcdef ghij
1. def abc ghij
2. def ghi abc j //接下来, j 步步前移
3. def ghi ab jc
4. def ghi a j bc
5. def ghi j abc
下面,再针对上述过程,画个图清晰说明下,如下所示:


def ghi abc jk
当 p1 指向 a, p2 指向 j 时,由于 p2+m 越界,那么此时 p1, p2 不要变
这里 p1 之后( abcjk)就是尾巴,处理尾巴只需将 j,k 移到 abc 之前,得到最终序列,代码
编写如下:

#include<iostream>
#include<string>
using namespace std;
void rotate(string & str, int m)
{
	if(str.length() == 0 || m <= 0)
		return;
	int n = str.length();
	if (m%n <= 0)
		return;
	int p1 = 0, p2 = m;
	int k = (n - m) - n%m;//表示可以平移的位数
	while (k--)
	{
		swap(str[p1], str[p2]);
		p1++;
		p2++;
	}//表示平移到了界限出  就是后面的字符串的个数不够平移的位数  
	//下面考虑怎么设置吧剩余的字符串 进行平移
	int r = n - p2;
	while (r--)
	{
		int i = p2;
		while (i > p1)
		{
			swap(str[i], str[i - 1]);
			i--;
		}
		p2++;
		p1++;
	}
}
int main()
{
	string ch = "abcdefghijk";
	rotate(ch, 3);
	cout<<ch << endl;
	system("pause");
	return 0;
}



你可能感兴趣的:(程序员编程艺术第一章(第二节))