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

BF算法和RK算法

用途:主要用于解決字符串匹配問(wèn)題

一、準(zhǔn)備

#define MAXSIZE 40    /* 存儲(chǔ)空間初始分配量 */
#define d 26 //進(jìn)制
typedef int Status;   /* Status是函數(shù)的類型,其值是函數(shù)結(jié)果狀態(tài)代碼吠卷,如OK等 */
typedef char String[MAXSIZE + 1];

生成一個(gè)S[0]為字符串長(zhǎng)度的字符串S

Status strAssign(String S,char *c){
  
  if (strlen(c)>MAXSIZE) {
      return ERROR;
  }else{
      S[0] = strlen(c);
      for (int i = 1; i<=S[0]; i++) {
          S[i] = c[i-1];
      }
  }
  return OK;
}

打印字符串S

void stringPrint(String S){
  for (int i = 1; i<=S[0]; i++) {
      printf("%c",S[i]);
  }
  printf("\n");
} 

二沦零、BF算法-爆風(fēng)匹配算法

思路:
1. 分別利用計(jì)數(shù)指針i和j指示主串S和模式T中當(dāng)前正待比較的字符位置,i初值為1,j的初值為1;
2. 如果2個(gè)串均為比較到串尾,即i和j均小于等于S和T的長(zhǎng)度時(shí), 則循環(huán)執(zhí)行以下的操作:
S[i]和T[j]比較,若相等,則i 和 j分別指示串中下一個(gè)位置,繼續(xù)比較后續(xù)的字符;
若不相等,指針后退重新開(kāi)始匹配. 從主串的下一個(gè)字符串(i = i - j + 2)起再重新和模式第一個(gè)字符(j = 1)比較;
3. 如果j > T.length, 說(shuō)明模式T中的每個(gè)字符串依次和主串S找中的一個(gè)連續(xù)字符序列相等,則匹配成功,返回和模式T中第一個(gè)字符的字符在主串S中的序號(hào)(i-T.length);否則匹配失敗,返回0;

int index_BF(String S, String T){
 //i為主串下標(biāo)
 int i = 1;
 //j為子串下標(biāo)
 int j = 1;
 
 while (i<=S[0]&&j<=T[0]) {
     if (S[i] == T[j]) {
         //比較兩個(gè)字母相等時(shí)路操,比較下一個(gè)字母
         i++;
         j++;
     }else{
         //不想等時(shí),從主串開(kāi)始比較的字符的下一個(gè)字母重新開(kāi)始比較屯仗,j賦值為1
         i = i - j +2;
         j = 1;
     }
 }
 //當(dāng)子串全部遍歷完成,則匹配成功
 if(j>T[0]){
     return i-T[0];
 }
 return -1;
}

三祭钉、RK算法-字符串匹配

思路:
用哈希值相等來(lái)比較,設(shè)計(jì)哈希公式(T[i]-'a') x d^(T.length-i),i從1開(kāi)始
1.算出子串的哈希值慌核,比較i位置的主串上與子串長(zhǎng)度相等的字母的哈希值
2.當(dāng)哈希值不相等的時(shí)候,計(jì)算下i+1位置的值等于i位置的值減去最高位的值再乘以進(jìn)制垫桂,再加上i+T.length位置的值
3.當(dāng)相等時(shí),再進(jìn)行二次字母匹配

算出d進(jìn)制下的最高位

int getMaxValue(int m){
  int h = 1;
  for (int i = 0; i<m-1; i++) {
      h = h * d;
  }
  return h;
}

二次字母匹配

Status isMatch(String S, int i, String T){
  for (int j = i; j<=T[0]; j++) {
      if(S[j] != T[j-i+1])
          return FALSE;
  }
  return TRUE;
}   
int index_RK(String S, String T){
  //A T的哈希值
  unsigned int A = 0;
  //St S中與T長(zhǎng)度相等的字符的哈希值
  unsigned int St = 0;
  
  //獲取A和St的哈希值
  for (int i = 1; i<=T[0]; i++) {
      A = (A * d) + T[i] -'a';
      St = (St *d) + S[i] - 'a';
  }
  int hValue = getMaxValue(T[0]);
  for (int i = 1; i<=S[0] - T[0] +1; i++) {
      if (A == St) {
          if (isMatch(S, i, T)) {
              return i;
          }
      }else{
          St = (St - (S[i] - 'a')*hValue)*d + S[i+T[0]]-'a';
      }
  }
  
  return -1;
}

main函數(shù)

int main(int argc, const char * argv[]) {
  // insert code here...
  int i;
  String s1,s2;
  
  strAssign(s1, "abcdex");
  printf("s1子串為");
  stringPrint(s1);
  
  
  strAssign(s2, "dex");
  printf("s2子串為");
  stringPrint(s2);
  
  i = index_RK(s1, s2);
  printf("i = %d\n",i);
  return 0;
}

demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市疼鸟,隨后出現(xiàn)的幾起案子庙曙,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件张抄,死亡現(xiàn)場(chǎng)離奇詭異洼怔,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)极谊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)矾缓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)稻爬,“玉大人,你說(shuō)我怎么就攤上這事琉雳∮蚜觯” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵束倍,是天一觀的道長(zhǎng)盟戏。 經(jīng)常有香客問(wèn)我,道長(zhǎng)柿究,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任婶肩,我火速辦了婚禮貌夕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苗膝。我一直安慰自己,他們只是感情好辱揭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布问窃。 她就那樣靜靜地躺著,像睡著了一般域庇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上熟呛,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天尉姨,我揣著相機(jī)與錄音,去河邊找鬼九府。 笑死覆致,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的煌妈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼笔链,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鉴扫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起坪创,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤莱预,失蹤者是張志新(化名)和其女友劉穎项滑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宋渔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年皇拣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了薄嫡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吩坝,死狀恐怖哑蔫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鸳址,我是刑警寧澤泉懦,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布崩哩,位于F島的核電站,受9級(jí)特大地震影響酣栈,放射性物質(zhì)發(fā)生泄漏汹押。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一窖维、第九天 我趴在偏房一處隱蔽的房頂上張望妙痹。 院中可真熱鬧,春花似錦琳轿、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至塘偎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吟秩,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工闹伪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留壮池,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓厅克,卻偏偏與公主長(zhǎng)得像证舟,于是被迫代替她去往敵國(guó)和親窗骑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子女责,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容