思路一:回溯法 這種匹配思路其實就是不斷地減掉s和p的可以匹配首部,直至乙個或兩個字串被減為空的時候,根據最終情況來得出結論。
如果只是兩個普通字串進行匹配,按序遍歷比較即可:
if( s.charat(i) == p.charat(i) )
如果正規表示式字串p只有一種"."一種特殊標記,依然是按序遍歷比較即可 :
if( s.charat(i) == p.charat(i) || p.charat(i) == '.' )
上述兩種情況實現時還需要判斷字串長度和字串判空的操作。
i元素需要出現0次,我們就保持s不變,將p的減掉兩個元素,呼叫ismatch。例如s:bc、p:a*bc,我們就保持s不變,減掉p的"a*",呼叫ismatch(s:bc,p:bc)。
i元素需要出現一次或更多次,先比較i元素和s首元素,相等則保持p不變,s減掉首元素,呼叫ismatch。例如s:aabb、p:a*bb,就保持p不變,減掉s的首元素,呼叫ismatch(s:abb,p:a*bb)。
此時存在一些需要思考的情況,例如s:abb、p:a*abb,會用兩種方式處理:
按照上述第二種情況比較i元素和s首元素,發現相等就會減掉s的首字元,呼叫ismatch(s:bb,p:a*abb)。在按照上述第一種情況減去p的兩個元素,呼叫ismatch(s:bb,p:abb),最終導致false。
直接按照上述第一種情況減去p的兩個元素,呼叫ismatch(s:abb,p:abb),最終導致true。
所以說這算是一種暴力方法,會將所有的情況走一邊,看看是否存在可以匹配的情況。
public boolean ismatch(string s, string p) else if (headmatched)else
}
時間複雜度:o((n+m)*2^(n+m/2)) n和m分別是s和p的長度
思路二:動態規劃法 本題的dp陣列的含義就是:dp[i][j]就是s的前i個元素是否可以被p的前j個元素所匹配。
我們知道了dp陣列的含義之後就知道了dp陣列的幾個細節:
dp[0][0]一定是true,因為s為空且p也為空的時候一定是匹配的;dp[1][0]一定是false,因為s有乙個字元但是p為空的時候一定是不匹配的。
這個boolean型別的dp陣列的大小應該是dp[s.length+1][p.length+1],因為我們不僅僅要分別取出s和p的所有元素,還要表示分別取s和p的0個元素時候(都為空)的情況。
當寫到dp[s.length][p.length]的時候,我們就得到了最終s和p的匹配情況。
dp[1][0]~dp[s.length][0]這一列都是false,因為s不為空但是p為空一定不能匹配。
所以建立好dp陣列之後,初始化dp[0][0]=true、dp[0][1]=false、dp[1][0]~dp[s.length][0]都是false。然後將第一行即dp[0][2]到dp[0][p.length]的元素初始化。
第一行初始化思路:如果不為空的p想要匹配上為空的s,因為此時p已經不為空,則需要p是"a*"、"b*"、"c*"。。。這種形式的才能匹配上。
然後填寫陣列的其餘部分,這個過程中如果p.charat(j)=='*\'依然是遵循上題中的兩種情況;否則就判斷兩個字串的i和j號字元是否相等,相等則分別減除當前字元繼續判斷,不相等則直接等於false。
public boolean ismatch(string s, string p)
//填寫dp陣列剩餘部分
for (int i=0;i
時間複雜度:o(n*m) n和m分別是s和p的長度
正規表示式 匹配
字串 void abtr quint32 ab 表示乙個正規表示式 template class bidirectionaliterator class allocator std allocator sub match bidirectionaliterator class match resul...
正規表示式匹配
請實現乙個函式用來匹配包括 和 的正規表示式。模式中的字元 表示任意乙個字元,而 表示它前面的字元可以出現任意次 包含0次 在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串 aaa 與模式 a.a 和 ab ac a 匹配,但是與 aa.a 和 ab a 均不匹配 解法 首先要想到用遞迴處理...
正規表示式匹配
請實現乙個函式用來匹配包括 和 的正規表示式。模式中的字元 表示任意乙個字元,而 表示它前面的字元可以出現任意次 包含0次 在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串 aaa 與模式 a.a 和 ab ac a 匹配,但是與 aa.a 和 ab a 均不匹配 class solutio...