子串的匹配
子串匹配——不回溯算法
(转)
子串匹配当然也可以使用不回溯的方式实现,这个算法是笔者在作一个模糊查询的实现的时候想到的,没有确认和通常算法的异同,可能是一个很平常的思想:)。实现的思想很简单:每次比较子串长度的大字符串,若相等则返回,否则在大字符串中的起始位置递进,直到大字符串结束。
实现源码为:
int FindSubString(const char* src,const char* sub) { int srcl = strlen(src); int subl = strlen(sub);
if (subl > srcl) return -1;
bool HasFound = false;
int l = 0; int r = subl - 1;
while ((r < srcl) && !HasFound) { int i; for (i = 0; i <= subl - 1; ++i) { if (src[i + l] != sub[i]) { l++; r++; break; } }
if (i > subl - 1) //找到了 HasFound = true; }
if (HasFound) { return l; }
return -1; } |
上面实现有一个不好处理的地方就是,当当前大字符串中子串不匹配时候,跳出后不好处理返回标志问题(代码中红色部分),因此可以将对两个相同长度字符串判断相等放到一个函数中实现,则这个实现就更加易于理解:
bool CompareEqual(const char* src,const char* sub,int l) { for (int i = 0; i <= l; ++i) { if (src[i] != sub[i]) { return false; } }
return true; } |
int FindSubString(const char* src,const char* sub) { int srcl = strlen(src); int subl = strlen(sub);
if (subl > srcl) return -1;
bool HasFound = true;
int l = 0; int r = subl - 1;
while (r < srcl) { if (CompareEqual(src + l,sub,subl - 1)) { return l; } else { l++; r++; } }
return -1; } |
子串匹配——回溯算法
子串的匹配是一个很常见的问题,意思就是说在一个给定的大字符串中寻找给定的子字符串。这是一个很经典的问题,包括一代宗师D.Knuth都在这个问题上有很深入的研究,并提出了所谓的KMP算法。当然这个问题的一个最直观的算法就是这里给出的回溯法。
回溯法求解子串的过程为:依次遍历大字符串和子串,当发现不相等的时候就回溯到上次起始字符的下一个字符继续,并给子串起始位置清零。当遍历完整个大字符串(没有找到)或者遍历完子串(找到)则算法退出。
实现源码为:
int FindSubString(const char* src,const char* sub) { int srcl = strlen(src); int subl = strlen(sub);
if (subl > srcl) return -1;
int i = 0; int j = 0;
while ((i < srcl) && (j < subl)) { if (src[i] == sub[j]) { i++; j++; } else { i = i - j + 1; //回溯,位置确定请根据已遍历字符串长度为基点计算 j = 0; } }
if (j >= subl) { return i - subl; }
return -1;
} |
0 0 0 (请您对文章做出评价)
子串的匹配是一个很常见的问题,意思就是说在一个给定的大字符串中寻找给定的子字符串。这是一个很经典的问题,包括一代宗师D.Knuth都在这个问题上有很深入的研究,并提出了所谓的KMP算法。当然这个问题的一个最直观的算法就是这里给出的回溯法。
回溯法求解子串的过程为:依次遍历大字符串和子串,当发现不相等的时候就回溯到上次起始字符的下一个字符继续,并给子串起始位置清零。当遍历完整个大字符串(没有找到)或者遍历完子串(找到)则算法退出。
实现源码为:
int FindSubString(const char* src,const char* sub) { int srcl = strlen(src); int subl = strlen(sub); if (subl > srcl) return -1; int i = 0; int j = 0; while ((i < srcl) && (j < subl)) { if (src[i] == sub[j]) { i++; j++; } else { i = i - j + 1; //回溯,位置确定请根据已遍历字符串长度为基点计算 j = 0; } } if (j >= subl) { return i - subl; }
return -1; } |