字串匹配問題:
有乙個字串 str1= 「010101010101010010101010101」,和乙個子串 str2=「0101010100」
現在要判斷 str1 是否含有 str2, 如果存在,就返回第一次出現的位置, 如果沒有,則返回-1
如果用暴力匹配的思路,並假設現在 str1 匹配到 i 位置,子串 str2 匹配到 j 位置,則有:
如果當前字元匹配成功(即 str1[i] == str2[j]),則 i++,j++,繼續匹配下乙個字元
如果失配(即 str1[i]! = str2[j]),令 i = i - (j - 1),j = 0。相當於每次匹配失敗時,i 回溯,j 被置為 0。
用暴力方法解決的話就會有大量的回溯,每次只移動一位,若是不匹配,移動到下一位接著判斷,浪費了大量的時間。(不可行!)
暴力匹配演算法實現.
暴力匹配的**實現:
public class violencematch
public static int violencematch(string str1,string str2)else
} //判斷是否匹配成功
if(j == s2len)else
}}
kmp 是乙個解決模式串在文字串是否出現過,如果出現過,最早出現的位置的經典演算法。
knuth-morris-pratt 字串查詢演算法,簡稱為 「kmp 演算法」,常用於在乙個文字串 s 內查詢乙個模式串 p 的出現位置,這個演算法由 donald knuth、vaughan pratt、james h. morris 三人於 1977 年聯合發表,故取這 3 人的姓氏命名此演算法。
kmp 方法演算法就利用之前判斷過資訊,通過乙個 next 陣列,儲存模式串中前後最長公共子串行的長度,每次回溯時,通過 next 陣列找到,前面匹配過的位置,省去了大量的計算時間。
字串匹配問題:
有乙個字串 str1= 「bbc abcdab abcdabcdabde」,和乙個子串 str2=「abcdabd」
現在要判斷 str1 是否含有 str2, 如果存在,就返回第一次出現的位置, 如果沒有,則返回-1
要求:使用 kmp 演算法完成判斷,不能使用簡單的暴力匹配演算法.
思路分析:
舉例來說,有乙個字串 str1 = 「bbc abcdab abcdabcdabde」,判斷,裡面是否包含另乙個字串 str2 =「abcdabd」?
重複第一步,還是不符合,再後移
一直重複,直到str1有乙個字元與str2的第乙個字元符合為止
接著比較字串和搜尋詞的下乙個字元,還是符合。
遇到 str1 有乙個字元與 str2 對應的字元不符合。
怎麼做到把剛剛重複的步驟省略掉?可以對 str2 計算出一張《部分匹配表》,這張表的產生在後面介紹
已知空格與d不匹配時,前面六個字元」abcdab」是匹配的。查表可知,最後乙個匹配字元b對應的」部分匹配值」為2,因此按照下面的公式算出向後移動的位數: 移動位數 = 已匹配的字元數 - 對應的部分匹配值 因為 6 - 2 等於4,所以將搜尋詞向後移動 4 位。
因為空格與 a 不匹配,繼續後移一位。
逐位比較,直到發現 c 與 d 不匹配。於是,移動位數 = 6 - 2,繼續將搜尋詞向後移動 4 位。
介紹《部分匹配表》怎麼產生的。先介紹字首,字尾是什麼
「部分匹配值」就是」字首」和」字尾」的最長的共有元素的長度。以」abcdabd」為例,
」部分匹配」的實質是,有時候,字串頭部和尾部會有重複。比如,」abcdab」之中有兩個」ab」,那麼它的」部分匹配值」就是 2(」ab」的長度)。搜尋詞移動的時候,第乙個」ab」向後移動 4 位(字串長度- 部分匹配值),就可以來到第二個」ab」的位置。
到此 kmp 演算法思想分析完畢!
kmp演算法的**實現如下:
public class kmpalgorithm
//獲取到乙個字串(子串)的部分匹配值表
public static int kmpnext(string dest)
if(dest.charat(i) == dest.charat(j))
next[i] = j;
} return next;
} /**
* * @param str1 源字串
* @param str2 子串
* @param next 子串的部分匹配表
* @return -1沒有匹配到,否則返回第乙個匹配到位置
*/public static int kmpsearch(string str1,string str2,int next)
if(str1.charat(i) == str2.charat(j))
if(j == str2.length())
} return -1;
}
}
程式設計師必備十大演算法3 歸併排序
十大演算法之歸併排序首先要有分治的思想 歸併排序的過程 1 建立歸併函式入口mergesort a,n a是陣列a,n為陣列長度 入口中要有乙個動態分配陣列,長度為n int malloc nsizeof int 2 建立乙個msort函式msort a,arr,0,n 1 用來做二分0和n 1就是...
程式設計師必備十大演算法 最短路徑(1)
最短路徑的演算法大致可以分為三種,不過每一種的演算法都有所不同 在時間複雜度 空間複雜度 負權 有負權的邊 是否可以檢驗有沒有負權或者帶負權的邊 這個演算法比較簡單,暴力解決,時間複雜度為pow n,3 空間複雜度為pow n,2 可以處理負權和帶負權邊的演算法 最短路徑 1 include usi...
程式設計師必備十大演算法 貪心演算法1 找錢問題
貪心演算法比較侷限,因為在決策上存在分歧,還有待證明,但是和動態規劃的思想一樣,都是從區域性最優解到整體最優解 今天講一下貪心演算法可以解決的其中乙個問題 找錢問題 首先說說一下思路,也就是核心演算法 找錢的規則是盡可能少的紙幣數找齊,找不齊就說 找不齊 找齊就輸出找錢的方法和紙幣張數,每張紙幣的張...