程式設計之美-3.1字串移位包含問題
假設字串s1=AABCD,s2=CDAA,判斷s2是否可以通過S1的迴圈移位得到字串包含。
如 s1移兩位: 1.ABCDA->2.BCDAA 則此時包含了 S2="CDAA"
解題思路:
分解s1的迴圈移位得到:
AABCD,ABCDA,BCDAA,CDAAB,.....
如果我們將前面移走的字串保留下來,則有:
AABCD,AABCDA,AABCDAA,AABCDAAB,AABCDAABC,AABCDAABCD
這裡,我們可以發現,實際對s1的迴圈移位得到的字串實際為s1s1。
那麼我們判斷s2是否可以通過s1迴圈移位得到包含,則只需要判斷s1s1中是否含有s2即可以。
用提高空間複雜度來換取時間複雜度的減低的目的。
函式名: strstr
包含檔案:string.h 函式原型:extern char *strstr(char *str1, char *str2); 功能:找出str2字串在str1字串中第一次出現的位置(不包括str2的串結束符)。
返回值:返回該位置的指標,如找不到,返回空指標。
其引數是傳統的char *型字串,string型資料型別是不能作為其引數的。但可以通過string成員函式string::c_str()轉換成char*型別。象這樣呼叫:
strstr(str1.c_str(), str2.c_str())
#include<iostream> #include<string> using namespace std; bool rotstr(string src,string des) { string tmp = src; src=src+tmp; if(strstr(src.c_str(),des.c_str())==NULL) { return false; } return true; } int main() { string src="AABBCD"; string des="DAAB"; if(rotstr(src,des)) cout<<"the string des is included in the rotated string of src "<<endl; else cout<<"the string des is not included in the rotated string of src "<<endl; return 0; }
擴充套件:
找出s2中第一個字元在s1的位置記為p1,找出s2中最後一個字元在s1中可能的位置記為p2,計算所有的p1與p2間的差值,若等於s2的長度,則比較p1與p2間的字串與s2,若兩者相等則返回true,否則返回false
#include<iostream> #include<string> #include<vector> using namespace std; bool rotstr(string src,string des) { //用vecPos1儲存dest字串第一個字元在src中可能出現的位置 //用vecPos2儲存dest字串最後一個字元在src中可能出現的位置 vector<int> vecPos1; vector<int> vecPos2; string str=src; int substrpos=str.find(des[0]); int pos=substrpos; //pos為字元在字串中的位置 while(substrpos!=-1) { cout<<pos<<endl; vecPos1.push_back(pos); str=src.substr(pos+1,src.length()-pos-1); substrpos=str.find(des[0]); pos=pos+1+substrpos; } str=src; substrpos=str.find(des[des.size()-1]); pos=substrpos; while(substrpos!=-1) { cout<<pos<<endl; vecPos2.push_back(pos); str=src.substr(pos+1,src.length()-pos-1); substrpos=str.find(des[des.size()-1]); pos=pos+1+substrpos; } int p1,p2; int len; string s; for(int i=0;i<vecPos1.size();i++) { for(int j=0;j<vecPos2.size();j++) { p1=vecPos1[i]; p2=vecPos2[j]; //最後一個字元出現在第一個字元前 if((p2-p1)<0) len=src.size()-p1+p2+1; //最後一個字元出現在第一個字元後 else len=p2-p1+1; if(len==des.size()) { if(p2-p1>=0) s=src.substr(p1,p2-p1+1); else s=src.substr(p1,src.size()-p1)+src.substr(0,p2+1); if(s==des) { return true; } } } } return false; } int main() { string src="AABBCD"; string des="DAAB"; if(rotstr(src,des)) cout<<"the string des is included in the rotated string of src "<<endl; else cout<<"the string des is not included in the rotated string of src "<<endl; int i; cin>>i; return 0; }
PS:
檢測兩個字串是否相等
對於C:strcmp(str1,str2)==0
對於C++: str1==str2
原因:C++string類過載了==運算子以便檢測字串的內容是否相等
對於java:str1.equals(str2)
說明:java中也有str1==str2 但是表達的含義不同
java的物件變數與c++不同,java的物件變數可以看做C++的指標
如:Date birth; //java
等價於:Date * birth; // c++
所以str1==str2 是判斷兩個指標所指向的地址是否相同,而不是指標所指向的內容是否相同
所以java中檢測兩個字串是否相等用:str1.equals(str2)或者:str1.compareTo(str2)