數(shù)據(jù)結(jié)構(gòu)與算法13-BF&RK算法

有一個主串S = {a, b, c, a, c, a, b, d, c}, 模式串T = { a, b, d } ; 請找到模式串在主串中第一次出現(xiàn)的位置;
提示: 不需要考慮字符串大小寫問題, 字符均為小寫字母

BF算法

BF算法弓乙,即暴力(Brute Force)算法日麸,是普通的模式匹配算法,BF算法的思想就是將目標串S的第一個字符與模式串T的第一個字符進行匹配毁靶,若相等,則繼續(xù)比較S的第二個字符和 T的第二個字符优构;若不相等疗琉,則比較S的第二個字符和T的第一個字符,依次比較下去秒咐,直到得出最后的匹配結(jié)果谬晕。BF算法是一種蠻力算法。

算法思想

首先S[1]和T[1]比較携取,若相等攒钳,則再比較S[2]和T[2],一直到T[M]為止雷滋;若S[1]和T[1]不等不撑,則S向右移動一個字符的位置,再依次進行比較晤斩。如果存在k焕檬,1≤k≤N,且S[k+1…k+M]=T[1…M]澳泵,則匹配成功实愚;否則失敗。
該算法最壞情況下要進行M*(N-M+1)次比較,時間復雜度為O(M * N)腊敲。

代碼實現(xiàn)
int Index(String S, String T, int pos) {
    int i = pos;
    int j = 1;
    while (i <= S[0] && j <= T[0]) {
        if (S[i] == T[j]) {
            i++;
            j++;
        } else {
            i = i - j + 2;
            j = 1;
        }
    }
    
    if (j > T[0]) {
        return i - T[0];
    } else {
        return -1;
    }
    
    return 0;
}

RK算法

RK 算法的全稱叫作 Rabin-Karp 算法击喂,是為了紀念它的兩個發(fā)明者而這樣命名的。 這個算法其實就是剛剛 BF 算法的升級版碰辅。

在 BF 算法中懂昂,每次都要對 m 個字符逐個進行比較,這就大大降低了算法的效率没宾。這時候凌彬,我們引入哈希算法,對子串逐個求哈希值榕吼,然后與模式串的哈希值進行比較來判斷兩個子串是否匹配。在不考慮哈希沖突的情況下勉失,數(shù)字之間的比較就非掣迹快了。

解題思路

1.首先把字母轉(zhuǎn)換成數(shù)字乱凿,將字母-'a'的值單純字母的對應(yīng)的數(shù)字

例如
a - a = 0;
b - a = 1;
c - a = 2;

  1. 將小寫字母字符串轉(zhuǎn)換成數(shù)字顽素,利用字母26進制

例如
“cba” = 'c' * 26 ^ 2 + 'b' * 26 ^ 1 + 'a' * 26 ^ 0
“cba” = 2 * 26 ^ 2 + 1 * 26 ^ 1 + 0 * 26 ^ 0

  1. 主串拆分的子串之間的關(guān)系

例如
主串: d b c e d b
= 3 * 26 ^ 2 + 1 * 26 ^ 1 + 2 * 26 ^ 0
主串: d b c e d b
= 1 * 26 ^ 2 + 2 * 26 ^ 1 + 4 * 26 ^ 0

子串哈希值求解的規(guī)律:

相鄰的2個子串s[i]與s[i + 1],對應(yīng)的哈希值計算公式有交集徒蟆,也就是說我們可以使用s[i - 1] 計算出s[i]的哈希值胁出。

St[i] = (St[i - 1] - d ^ (m - 1) * (s[i] - 'a')) * d + (s[i + m] - 'a')

  1. 處理哈希沖突
  • 設(shè)計更復雜的哈希公式
  • 如果哈希值相等,重新核實
代碼實現(xiàn)
#define d 26

int isMatch(char *S, int i, char *P, int m) {
    int is, ip;
    for (is = i, ip = 0; is != m && ip != m; is++, ip++) {
        if (S[is] != P[ip]) {
            return 0;
        }
    }
    
    return 1;
}

/*
 d ^ (m - 1) 位的值
 */
int getMaxValue(int m) {
    int j = 1;
    for (int i = 0; i < m - 1; i++) {
        j = j * d;
    }
    return j;
}

int Index(char *S, char *P) {
    int n = (int)strlen(S);
    int m = (int)strlen(P);
    
    unsigned int A = 0;
    unsigned int St = 0;
    
    for (int i = 0; i != m; i++) {
        A = (d * A + (P[i] - 'a'));
        St = (d * St + (S[i] - 'a'));
    }
    
    int hValue = getMaxValue(m);
    for (int i = 0; i <= n - m; i++) {
        if (A == St && isMatch(S, i, P, m)) {
            return i + 1;
        }
        St = (St - hValue * (S[i] - 'a')) * d + (S[i + m] - 'a');
    }
    
    return -1;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末段审,一起剝皮案震驚了整個濱河市全蝶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寺枉,老刑警劉巖抑淫,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異姥闪,居然都是意外死亡始苇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門筐喳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來催式,“玉大人,你說我怎么就攤上這事避归∪僭拢” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵梳毙,是天一觀的道長喉童。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么堂氯? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任蔑担,我火速辦了婚禮,結(jié)果婚禮上咽白,老公的妹妹穿的比我還像新娘啤握。我一直安慰自己,他們只是感情好晶框,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布排抬。 她就那樣靜靜地躺著,像睡著了一般授段。 火紅的嫁衣襯著肌膚如雪蹲蒲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天侵贵,我揣著相機與錄音届搁,去河邊找鬼。 笑死窍育,一個胖子當著我的面吹牛卡睦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播漱抓,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼表锻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乞娄?” 一聲冷哼從身側(cè)響起瞬逊,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仪或,沒想到半個月后码耐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡溶其,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年骚腥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓶逃。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡束铭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厢绝,到底是詐尸還是另有隱情契沫,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布昔汉,位于F島的核電站懈万,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜会通,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一口予、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涕侈,春花似錦沪停、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至端三,卻和暖如春舷礼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背郊闯。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工妻献, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虚婿。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓旋奢,卻偏偏與公主長得像泳挥,于是被迫代替她去往敵國和親然痊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349