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++实现位图排序实例