26.左旋轉字符串

 題目:
定義字符串的左旋轉操作:把字符串前面的若干個字符移動到字符串的尾部。
如把字符串abcdef 左旋轉2 位得到字符串cdefab。請實現字符串左旋轉的函數。
要求時間對長度爲n 的字符串操作的複雜度爲O(n),輔助內存爲O(1)。
分析:如果不考慮時間和空間複雜度的限制,
最簡單的方法莫過於把這道題看成是把字符串分成前後兩部分,
通過旋轉操作把這兩個部分交換位置。
於是我們可以新開闢一塊長度爲n+1 的輔助空間,
把原字符串後半部分拷貝到新空間的前半部分,在把原字符串的前半部分拷貝到新空間的後
半部分。
不難看出,這種思路的時間複雜度是O(n),需要的輔助空間也是O(n)。

把字符串看成有兩段組成的,記位XY。左旋轉相當於要把字符串XY 變成YX。
我們先在字符串上定義一種翻轉的操作,就是翻轉字符串中字符的先後順序。把X 翻轉後
記爲XT。顯然有(XT)T=X。
我們首先對X 和Y 兩段分別進行翻轉操作,這樣就能得到XTYT。
接着再對XTYT 進行翻轉操作,得到(XTYT)T=(YT)T(XT)T=YX。正好是我們期待的結果。
分析到這裏我們再回到原來的題目。我們要做的僅僅是把字符串分成兩段,
第一段爲前面m 個字符,其餘的字符分到第二段。
再定義一個翻轉字符串的函數,按照前面的步驟翻轉三次就行了。
時間複雜度和空間複雜度都合乎要求。

#include<iostream>
#include<string>

using namespace std;

void reverse(string &s,int begin,int end)
{
	if(begin<0||end<0)
		return;
	for(;begin<end;begin++,end--)
	{
		char temp=s[begin];
		s[begin]=s[end];
		s[end]=temp;
	}

}

void leftrev(string &s,int m)
{
	int n=s.size();
	if(m>n)
		return;
	reverse(s,0,m-1);
	reverse(s,m,n-1);
	reverse(s,0,n-1);
}

int main()
{
	string str="abcdefghijklmnopq";
	leftrev(str,4);
	cout<<str<<endl;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章