标签:
字符串匹配(string match)是在实际工程中经常会碰到的问题,通常其输入是原字符串(String)和子串(又称模式,Pattern)组成,输出为子串在原字符串中的首次出现的位置。通常精确的字符串搜索算法包括暴力搜索(Brute force),KMP。下面分析这几种方法并给出其实现。假设原字符串长度M,字串长度为N。
1. Brute force.
该方法又称暴力搜索,也是最容易想到的方法。
预处理时间 O(0)
匹配时间复杂度O(N*M)
主要过程:从原字符串开始搜索,若出现不能匹配,则从原搜索位置+1继续。
/*ret=0,find与text不匹配 *ret = -1,输入不符合要求 *ret = -2,find的长度小于text的长度 *若匹配,返回text中开始匹配的位置 */ int brute_force(const char *text, const char *find) { int ret = 0; if (text == NULL || find == NULL) { ret = -1; printf("func brute_force() err:%d\n", ret); return ret; } int find_len = strlen(find); int text_len = strlen(text); if (text_len < find_len) { ret = -2; printf("func brute_force() err:%d\n", ret); return ret; } char *pSmall = find; char *pBig = text; while (*pBig != '\0') { if (*pBig == *pSmall) { pBig++; pSmall++; } else { pSmall = find; pBig++; } if (*pSmall == '\0') { ret = (pBig - text) - (pSmall - find); break; } } return ret; }
2. KMP.
KMP是经典的字符串匹配算法。
预处理时间:O(M)
匹配时间复杂度:O(N)
主要过程:通过对字串进行预处理,当发现不能匹配时,可以不进行回溯。
int kmp(const char *text, const char *find) { //判断输入 int ret = 0; if (text == NULL || find == NULL) { ret = -1; printf("func brute_force() err:%d\n", ret); return ret; } //判断匹配字符串的长度 int find_len = strlen(find); int text_len = strlen(text); if (text_len < find_len) { ret = -2; printf("func brute_force() err:%d\n", ret); return ret; } //建立匹配数组 int next[find_len]; memset(next, 0, find_len*sizeof(int)); next[0] = 0; next[1] = 0; int j = 0; int i = 1; while (i < find_len) { if (j==0 || find[i] == find[j]) { i++; j++; if (find[i] != find[j]) { next[i] = j; } else { next[i] = next[j]; } } else { j = next[j]; } } i=0; j=0; while (i <=text_len && j<=find_len) { if (text[i]==find[j]) { i++; j++; } else { j = next[j]; if (j == 0) { i++; } } if (j==find_len) { ret = i - j; } } return ret; }
标签:
原文地址:http://blog.csdn.net/yiluohan0307/article/details/51320589