C++实现一维向量旋转算法(2)
思路四:旋转向量x实际上就是交换向量ab的两段,得到向量ba,这里a代表x的前i个元素。假设a比b短。将b分割成bl和br,使br的长度和a的长度一样。交换a和br,将ablbr转换成brbla。因为序列a已在它的最终位置了,所以我们可以集中精力交换b的两个部分了。由于这个新问题和原先的问题是一样的,所以我们以递归的方式进行解决。这种方法可以得到优雅的程序,但是需要巧妙的代码,并且要进行一些思考才能看出它的效率足够高。
//实现代码(略)
思路五:(最佳)将这个问题看做是把数组ab转换成ba,同时假定我们拥有一个函数可以将数组中特定部分的元素逆序。从ab开始,首先对a求逆,得到arb,然后对b求逆,得到arbr。最后整体求逆,得到(arbr)r,也就是ba。
reverse(0, i-1) /*cbadefgh*/ reverse(i, n-1) /*cbahgfed*/ reverse(0, n-1) /*defghabc*/
性能:求逆序的方法在时间和空间上都很高效,而且代码非常简短,很难出错。
C++代码实现如下:
/*************************************************************************
> File Name: vector_rotate.cpp
> Author: SongLee
************************************************************************/
#include<iostream>
#include<string>
using namespace std;
void reverse(string &s, int begin, int end)
{
while(begin < end)
{
char tmp = s[begin];
s[begin] = s[end];
s[end] = tmp;
++begin;
--end;
}
}
int main()
{
string s = "abcdefghijklmn";
cout << "The origin is: "<< s << endl;
int i;
cin >> i;
if(i > s.size())
{
i = i%s.size();
}
reverse(s, 0, i-1);
reverse(s, i, s.size()-1);
reverse(s, 0, s.size()-1);
cout << "The result is: "<< s << endl;
return 0;
}
三、扩展延伸
如何将向量abc旋转变成cba?
和前面的问题类似,此向量旋转对应着非相邻内存块的交换模型。解法很相似,即利用恒等式:cba = (arbrcr)r
注意:在面试或笔试时,如若出现向量旋转(内存块交换)问题,建议最好使用思路五答题,不仅高效而且简洁。
- 上一篇:C++变位词问题分析
- 下一篇:C++实现位图排序实例





