1. 程式人生 > >isSubstring子串判斷筆試題

isSubstring子串判斷筆試題

題目

原文:

Assume you have a method isSubstring which checks if one word is a substring of another. Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only one call to isSubstring ( i.e., “waterbottle” is a rotation of “erbottlewat”).

譯文:

假設你有一個isSubstring函式,可以檢測一個字串是否是另一個字串的子串。 給出字串s1和s2,只使用一次isSubstring就能判斷s2是否是s1的旋轉字串, 請寫出程式碼。旋轉字串:"waterbottle"是"erbottlewat"的旋轉字串。

解答

題目說我們使用一次isSubstring函式就可以判斷s2是否是s1的旋轉字串, 如果從原始字串s1和s2直接入手肯定不行,因為它們根本不存在子串關係。 如果不斷地旋轉字元,然後呼叫isSubstring,又需要呼叫多次的isSubstring。 而且通過旋轉字元再判斷,可以直接用等號判斷,根本用不上isSubstring。

既然如此,我們就要考慮去改變原始字串。要判斷a串是否是b串的子串, 一般情況下都會有b串長度大於a串,長度相等的話就直接判斷它們是不是相等的串了。 我們可以考慮把串s1變長,然後呼叫一次isSubstring判斷s2是否是s1變長後的子串, 如果是,就得出s2是s1的旋轉字串。s1怎麼變長呢?無非就是s1+s1或是s1+s2, s2一定是s1+s2的子串,因此這樣做沒有任何意義。而s1+s1呢? 我們就上面的例子進行討論:s1=waterbottle,s2=erbottlewat. 則:

s1 + s1 = waterbottlewaterbottle

很容易可以發現,s1+s1其實是把s1中每個字元都旋轉了一遍,而同時保持原字元不動。 比如waterbottle向右旋轉2個字條應該是:terbottlewa,但如果同時保持原字元不動, 我們得到的就是waterbottlewa,而terbottlewa一定是waterbottlewa的子串, 因為waterbottlewa只是在terbottlewa的基礎上再加上一條原字元不動的限制。 因此s1+s1將包含s1的所有旋轉字串,如果s2是s1+s1的子串,自然也就是s1 的旋轉字串了。

程式碼如下:

#include <iostream>
#include <string> using namespace std; bool isSubstring(string s1, string s2){ if(s1.find(s2) != string::npos) return true; else return false; } bool isRotation(string s1, string s2){ if(s1.length() != s2.length() || s1.length()<=0) return false; return isSubstring(s1+s1, s2); } int main(){ string s1 = "apple"; string s2 = "pleap"; cout<<isRotation(s1, s2)<<endl; //cout<<string::npos<<endl; return 0; }