• <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>
            隨筆-80  評論-24  文章-0  trackbacks-0
            KMP算法用來求解一個字符串是否是另外一個字符串的子串,算法復雜度為θ(n)。
            大致講解下KMP算法的思想,這里不做深究,因為網上一搜一大片,尤其以Matrix67講解的非常棒,可以參考:http://www.matrix67.com/blog/archives/115
            K
            MP的核心思想其實就是當在匹配的過程中,一旦發現當前字符mother[i]與child[j]不匹配,則將j向前移,而保持i不變,這樣就能使得i始終是向后移動的,所以能保證時間復雜度為θ(n)。具體j應該如何移動,則需要預處理子串child,得出next數組,然后根據next數組查找j該向前移動多少步。這里的思想是如果當前mother[i] != child[j],則應該使j = next[j],然后繼續匹配mother[i]與child[j]。next[j]的含義其實就是字符串0~next[j]是字符串0~j的后綴。理解了這個之后就可以看懂KMP代碼了。
            下面是實現代碼,實現的比較丑陋,講究看吧:

             1 static int compute_next(const char *str, int *next, int len) {
             2   if (!str || !next || len <= 0) {
             3     return -1; 
             4   }
             5   next[0] = -1; 
             6   int k = -1; 
             7   int i = 1;
             8   for (i; i < len; ++i) {
             9     while (k >= 0 && str[i] != str[k + 1]) {
            10       k = next[k];
            11     }   
            12     if (str[i] == str[k + 1]) {
            13       k++;
            14     }   
            15     next[i] = k;
            16   }
            17   return 0;
            18 }
            19 
            20 //KMP算法查找子串
            21 char *Strstr(const char *str1, const char *str2) {
            22   if (!str1 || !str2) {
            23     return NULL;
            24   }
            25   int str1len = strlen(str1);
            26   int str2len = strlen(str2);
            27   int *next = (int *)malloc(sizeof(int) * str2len);
            28 
            29   if (compute_next(str2, next, str2len) == -1) {
            30     return NULL;
            31   }
            32 
            33   int k = -1;
            34   int i = 0;
            35   for (; i < str1len; ++i) {
            36     while (k >= 0 && str1[i] != str2[k + 1]) {
            37       k = next[k];
            38     }
            39     if (str1[i] == str2[k + 1]) {
            40       k++;
            41     }
            42     if (k == str2len - 1) {
            43       free(next);
            44       next = NULL;
            45       return str1 + i - str2len + 1;
            46     }
            47   }
            48   free(next);
            49   next = NULL;
            50   return NULL;
            51 }

            poj1226題是典型的最長公共子串問題,題意是有若干個字符串,找出最長的一個子串的長度,該子串或者其反串是所有字符串的子串。數據比較弱,所以用strstr也可以ac。思想其實是找出這N個字符串中最短的串,假設其長度為l,然后依次枚舉該串的子串,不過這里可以枚舉子串的長度,從l開始枚舉,一旦發現該串或者其反串是所有串的子串,則輸出該長度。代碼如下:

             1 int main() {
             2   int cases, n, min_len, min_len_index, i, j, k, index, flag;
             3   char str_buf[105];
             4   char rev_buf[105];
             5   scanf("%d", &cases);
             6   while (cases--) {
             7     scanf("%d", &n);
             8     if (!n) {continue;}
             9     min_len = 105;
            10     min_len_index = -1;
            11     for (i = 0;i < n; ++i) {
            12       scanf("%s", strings[i]);
            13       string_len[i] = strlen(strings[i]);
            14       if (string_len[i] < min_len) {
            15         min_len = string_len[i];
            16         min_len_index = i;
            17       }
            18     }
            19 
            20     while (min_len) {
            21       //枚舉長度為min_len的子串
            22       for (i = 0; i <= string_len[min_len_index] - min_len; ++i) {
            23         for (index = 0, j = i; j < i + min_len; ++j, ++index) {
            24           str_buf[index] = strings[min_len_index][j];
            25           rev_buf[min_len - 1 - index] = strings[min_len_index][j];
            26         }
            27         str_buf[index] = '\0';
            28         rev_buf[index] = '\0';
            29         for (k = 1, flag = 1; k < n; ++k) {
            30           if (!Strstr(strings[k], str_buf) && !Strstr(strings[k], rev_buf)) {
            31             flag = 0;
            32             break;
            33           }
            34         }
            35         if (flag == 1) {
            36           goto end;
            37         }
            38       }
            39       min_len--;
            40     }
            41 end: printf("%d\n", min_len);
            42   }
            43   return 0;
            44 }
            posted on 2012-09-11 20:10 myjfm 閱讀(3222) 評論(0)  編輯 收藏 引用 所屬分類: 算法基礎
            91亚洲国产成人久久精品| 欧美久久久久久精选9999| 日韩乱码人妻无码中文字幕久久 | 久久精品国产亚洲AV香蕉| 精品久久久久久中文字幕| 日本亚洲色大成网站WWW久久 | 色播久久人人爽人人爽人人片aV | 久久精品无码专区免费青青| 色综合久久精品中文字幕首页 | 国产Av激情久久无码天堂| 国产午夜精品久久久久九九| 亚洲午夜无码久久久久| av午夜福利一片免费看久久| 天天做夜夜做久久做狠狠| 国产精品久久久亚洲| 久久这里只精品99re66| 国产99久久久国产精免费| 一本色道久久88—综合亚洲精品| 国产精品九九久久免费视频| 国产欧美一区二区久久| 亚洲中文久久精品无码ww16| 久久久中文字幕日本| 香蕉久久夜色精品国产小说| 亚洲AV无码1区2区久久| 久久这里的只有是精品23| 久久99精品久久久久久齐齐| 狠狠色丁香婷婷综合久久来 | 久久久久久人妻无码| 久久99热这里只有精品国产| 三级韩国一区久久二区综合| 国内精品欧美久久精品| 国产韩国精品一区二区三区久久| 久久亚洲AV成人无码软件| 无码人妻少妇久久中文字幕 | 99久久精品免费国产大片| 97久久香蕉国产线看观看| 久久久国产精品亚洲一区| 日韩精品久久久肉伦网站 | 久久婷婷五月综合97色| 午夜人妻久久久久久久久| 亚洲欧美日韩中文久久|