• <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)  編輯 收藏 引用 所屬分類: 算法基礎
            久久久久人妻一区二区三区vr | 国产L精品国产亚洲区久久| 久久国产精品-国产精品| 久久精品一区二区三区不卡| 国产毛片久久久久久国产毛片 | 亚洲欧美日韩精品久久亚洲区| 久久久高清免费视频| 国产精品一区二区久久| 日韩美女18网站久久精品| 久久亚洲欧美国产精品| 久久精品国产精品亚洲艾草网美妙| 久久无码国产专区精品| 66精品综合久久久久久久| 久久无码高潮喷水| 久久精品中文字幕有码| 精品亚洲综合久久中文字幕| 99久久综合国产精品免费| 国产精品岛国久久久久| 精品熟女少妇AV免费久久| 久久久精品人妻无码专区不卡| 久久久av波多野一区二区| 亚洲人AV永久一区二区三区久久 | 亚洲中文久久精品无码ww16| 久久高清一级毛片| 91久久精品无码一区二区毛片| 亚洲va久久久噜噜噜久久男同| 久久久免费观成人影院| 日本三级久久网| 77777亚洲午夜久久多喷| 久久久av波多野一区二区| 久久久久波多野结衣高潮| 亚洲人成电影网站久久| 久久久久久亚洲精品不卡 | 久久精品人妻中文系列| 色99久久久久高潮综合影院 | 国产三级精品久久| 伊人久久大香线蕉精品| 久久精品国产69国产精品亚洲 | 久久国产欧美日韩精品| 国产精品久久新婚兰兰| 伊人久久大香线焦AV综合影院|