青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

c++初學者

專注技術開發

[轉]字符串匹配算法(二)窮舉與自動機

窮舉法又叫暴力法。大多數程序員眼里,它是幼稚的,但大師們不這么認為。

Rob Pike, 最偉大的C 語言大師之一, 在《Notes on C Programming》中闡述了一個原則:花哨的算法比簡單算法更容易出bug、更難實現,盡量使用簡單的算法配合簡單的數據結構。而Ken Thompson——Unix 最初版本的設計者和實現者,禪宗偈語般地對Pike 的這一原則作了強調: 拿不準就窮舉(When in doubt , use brute force)。 而對于裝13愛好者來說,更是自豪的稱其使用的是BF算法。

窮舉法用在字符串匹配上,簡單的描述就是,檢查文本從0到n-m的每一個位置,看看從這個位置開始是否與模式匹配。這種方法還是有一些優點的,如:不需要預處理過程,需要的額外空間為常數,每一趟比較時可以以任意順序進行。

盡管它的時間復雜度為O(mn),例如在文本"aaaaaaaaaaaaaaaaaaaaaaaaaaa"中尋找"aaaaab"時,就完全體現出來了。但是算法的期望值卻是2n,這表明該算法在實際應用中效率不低。

C代碼如下:
  1. void BF(char *x, int m, char *y, int n) {
  2.    int i, j;
  3.    /* Searching */
  4.    for (j = 0; j <= n - m; ++j) {
  5.       for (i = 0; i < m && x[i] == y[i + j]; ++i);
  6.       if (i >= m)
  7.          OUTPUT(j);
  8.    }
  9. }
  10.   
如果我們注意到C庫函數是匯編優化過的,并通常能提供比C代碼更高的性能的話,我們可以用memcmp來完成每一趟比較過程,從而達到更好的性能:
  1. #define EOS '\0'
  2.    
  3. void BF(char *x, int m, char *y, int n) { 
  4.   char *yb; 
  5.   /* Searching */ 
  6.   for (yb = y; *y != EOS; ++y) 
  7.     if (memcmp(x, y, m) == 0) 
  8.       OUTPUT(y - yb);
  9. }
自動機的方法其實和窮舉法有點相似,都是用最簡單直白的方式來做事情。區別在于窮舉法是在計算,而自動機則是查表。盡管自動機的構造過程有一點點難解,要涉及到DFA的理論,但是自動機的比較過程那絕對是簡單到無語。

簡單說來,根據模式串,畫好了一張大的表格,表格m+1行σ列,這里σ表示字母表的大小。表格每一行表示一種狀態,狀態數比模式長度多1。一開始的狀態是0,也就是處在表格的第0行,這一行的每個元素指示了當遇到某字符時就跳轉到另一個狀態。每當跳轉到最終狀態時,表示找到了一個匹配。

語言表述起來還是比較啰嗦,看代碼就知道了:
  1. #define ASIZE 256
  2. int preAut(const char *x, int m, int* aut) {
  3.         int i, state, target, old;
  4.         for (state = 0, i = 0; i < m; ++i) {
  5.                 target = i + 1;
  6.                 old = aut[state * ASIZE + x[i]];
  7.                 aut[state * ASIZE + x[i]] = target;
  8.                 memcpy(aut + target * ASIZE, aut + old * ASIZE, ASIZE*sizeof(int));
  9.                 state = target;
  10.         }
  11.         return state;
  12. }
  13. void AUT(const char *x, int m, const char *y, int n) {
  14.         int j, state;
  15.         /* Preprocessing */
  16.         int *aut = (int*)calloc((m+1)*ASIZE, sizeof(int));
  17.         int Terminal = preAut(x, m, aut);
  18.         /* Searching */
  19.         for (state = 0, j = 0; j < n; ++j) {
  20.                 state = aut[state*ASIZE+y[j]];
  21.                 if (state == Terminal)
  22.                         OUTPUT(j - m + 1);
  23.         }
  24. }
注:原文的代碼使用一個有向圖的數據結構,我遵循大師的指引,改用了更簡單一點的數組

從代碼上我們很容易看出,自動機的構造需要時間是O(mσ),空間也是O(mσ)(嚴格來說這份代碼使用了O((m+1)σ)),但是一旦構造完畢,接下來匹配的時間則是O(n)。

匹配的過程前面已經說了,太簡單了沒什么好說的,這里就解釋一下構造過程吧!

我們構造的目標是對應模式長度,構造出同樣多的狀態,用0表示初始狀態,然后第一個字符用狀態1表示,第二個用狀態2表示,依次類推,直到最后一個字符,用m表示,也是最終狀態。

一開始,數組全都置0,,這個時候的自動機遇到任何字符都轉到初始狀態。然后給它看模式的第一個字符,假設這是'a'吧,告訴它,狀態0遇到'a'應該到一個新的狀態——狀態1,所以把第0行的第'a'列修改為1。而這個時候狀態1還是空白的,怎么辦呢?

這時候狀態0就想呀,在我被告知遇到'a'要去狀態1之前,我原本遇到'a'都要去狀態0的,也就是修改之前第'a'列所指的那個狀態,稱為old狀態吧;而現在我遇到'a'卻要去一個新的狀態,既然以前old狀態能處理遇到'a'之后的事情,那么我讓新的狀態像old狀態一樣就好了。于是狀態0把old狀態拷貝到狀態1。

現在輪到狀態1了,給它看第二個字符,它也如法炮制,指向了狀態2,又把old狀態拷貝給了狀態2。

于是,狀態機就在這種代代傳承的過程中構造完畢了。

雖然理論上自動機是最完美的匹配方式,但是由于預處理的消耗過大,實踐中,主要還是用于正則表達式。

結語:窮舉法與自動機各自走了兩個極端,因此都沒能達到綜合性能的最佳,本文之后介紹的算法,可以看成是在窮舉和自動機兩者之間取舍權衡的結果。

posted on 2008-11-11 13:07 大海 閱讀(1293) 評論(1)  編輯 收藏 引用 所屬分類: 圖像算法C++

評論

# re: [轉]字符串匹配算法(二)窮舉與自動機[未登錄] 2008-11-12 13:02 908971

學習了  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久婷婷国产综合尤物精品| 久久成人国产精品| 欧美高清视频免费观看| 在线观看av一区| 欧美 日韩 国产 一区| 久久久久久久尹人综合网亚洲| 国产九九精品| 久久精品国产清高在天天线| 亚洲一区二区三区在线视频| 国产精品免费视频xxxx| 亚洲欧美日韩电影| 午夜亚洲性色福利视频| 国产日韩成人精品| 美女视频网站黄色亚洲| 久久一区二区三区av| 亚洲第一区在线| 亚洲三级免费| 免费日韩精品中文字幕视频在线| 亚洲福利视频二区| 亚洲日本理论电影| 国产精品久久九九| 久久精品国产久精国产爱| 久久久精彩视频| 亚洲激情偷拍| 亚洲午夜91| 亚洲成色777777女色窝| 亚洲国产视频一区二区| 国产精品电影在线观看| 久久精品一区二区三区不卡牛牛| 久久久久久久精| 99国产精品久久久久老师 | 国产精品一区二区三区成人| 久久久夜夜夜| 欧美精品在欧美一区二区少妇| 亚洲一区美女视频在线观看免费| 午夜免费日韩视频| 91久久国产综合久久91精品网站| 亚洲国产一区二区精品专区| 国产精品视频一| 免费欧美网站| 国产精品免费一区二区三区观看| 欧美 日韩 国产在线| 国产精品久久久久久久久久ktv | 亚洲国产成人午夜在线一区 | 亚洲欧美日韩综合aⅴ视频| 欧美伊人久久久久久久久影院 | 欧美午夜不卡在线观看免费| 久久精品免费电影| 欧美精品日韩一区| 久久亚洲午夜电影| 国产精品国产三级国产aⅴ入口| 久久一区二区三区四区五区| 国产精品v一区二区三区| 亚洲国产精品成人va在线观看| 国产精品日韩一区| 亚洲精品一区二区三区四区高清 | 六月婷婷久久| 久久大综合网| 国产精品第一区| 亚洲国产欧美日韩另类综合| 国产综合色在线视频区| 99精品热视频只有精品10| 亚洲激情网站| 蜜臀va亚洲va欧美va天堂| 欧美在线观看视频一区二区三区| 欧美日韩激情小视频| 欧美激情偷拍| 在线电影国产精品| 久久久国产精彩视频美女艺术照福利 | 亚洲一区二区三区在线播放| 一本色道久久88综合亚洲精品ⅰ | 亚洲免费视频成人| aa级大片欧美三级| 欧美国产日本在线| 欧美成人有码| 亚洲黄色片网站| 久久综合网hezyo| 欧美福利一区| 亚洲精品综合久久中文字幕| 免费观看一区| 亚洲国内自拍| 在线亚洲欧美专区二区| 欧美视频不卡| 亚洲一级黄色片| 久久久久国产一区二区三区| 韩国自拍一区| 母乳一区在线观看| 亚洲精品乱码| 亚洲专区国产精品| 国产伦理一区| 久久久久久综合| 亚洲国产成人久久| 一本一本久久| 国产精品青草久久| 久久国产99| 亚洲电影av| 亚洲视频在线二区| 国产精品丝袜白浆摸在线| 午夜精品偷拍| 欧美国产三级| 午夜伦理片一区| 国产日韩在线看| 麻豆成人在线播放| 宅男噜噜噜66一区二区| 久久精品国产久精国产一老狼| 亚洲国产成人不卡| 欧美三区美女| 久久精品亚洲一区二区三区浴池| 91久久久一线二线三线品牌| 午夜精品久久久久久99热| 精品二区久久| 国产精品v日韩精品| 久久人人九九| 中文欧美字幕免费| 欧美激情一二三区| 久久精品av麻豆的观看方式| 亚洲靠逼com| 国产一区二区日韩| 欧美日韩一区在线视频| 久久精品日产第一区二区三区 | 亚洲欧美国产高清| 在线观看亚洲| 国产精品一二一区| 欧美精品在线观看一区二区| 欧美一区二区在线看| 亚洲精品欧美激情| 美女精品在线| 性8sex亚洲区入口| 一本色道综合亚洲| 最新成人av网站| 国产在线精品成人一区二区三区 | 亚洲深夜福利| 亚洲国产成人精品久久| 久久躁日日躁aaaaxxxx| 亚洲欧美日韩综合| 一区二区三区免费网站| 91久久精品网| 狠狠色狠狠色综合日日小说| 国产精品免费视频观看| 欧美成人一品| 久久天堂精品| 久久久国产亚洲精品| 校园春色综合网| 亚洲一区在线视频| 亚洲午夜精品久久| 亚洲视频在线观看网站| av成人激情| 99精品欧美| 9l国产精品久久久久麻豆| 亚洲毛片在线观看| 亚洲精品在线观| 亚洲精品一区在线观看| 亚洲精选久久| 亚洲精品永久免费| 99在线热播精品免费99热| 亚洲人成久久| 亚洲精品欧美一区二区三区| 亚洲欧洲精品一区二区精品久久久| 欧美国产精品久久| 亚洲第一区在线观看| 亚洲国产日韩欧美在线动漫| 亚洲欧洲精品一区二区精品久久久| 欧美激情亚洲视频| 亚洲人妖在线| 在线亚洲欧美| 欧美一区二区免费观在线| 欧美在线3区| 久久只有精品| 欧美日韩色婷婷| 国产欧美精品一区二区色综合| 国产一区在线观看视频| 狠狠色狠色综合曰曰| 91久久香蕉国产日韩欧美9色| 99国产精品久久久久久久久久 | 国产日韩在线亚洲字幕中文| 国产精品综合色区在线观看| 国外视频精品毛片| 亚洲日产国产精品| 亚洲永久免费| 久久综合九色综合久99| 亚洲国产精品电影在线观看| 日韩视频在线观看国产| 午夜精品成人在线视频| 美女视频黄a大片欧美| 欧美日韩在线一区二区三区| 国产一区二区电影在线观看| 亚洲日本一区二区三区| 午夜在线不卡| 欧美激情一区二区三区四区| 中文在线资源观看视频网站免费不卡| 亚洲欧美日韩电影| 欧美成人一区二区在线| 国产精品入口66mio| 亚洲国产精品久久91精品| 亚洲一区二区在线观看视频| 久久婷婷一区| 亚洲已满18点击进入久久| 免费一级欧美在线大片| 国产噜噜噜噜噜久久久久久久久| 亚洲欧洲美洲综合色网|