字符串模式匹配(Pattern Matching)之一:回溯法
来源:互联网 发布:paas容器集群优化 编辑:程序博客网 时间:2024/04/29 20:11
字符串模式匹配(Pattern Matching)之一:回溯法
概念:
设有两个字符串T和pat,若在串T中查找是否有与串pat相等的子串,则称串T为目标(Target),把pat 称为模式(Pattern),把这样查找模式在目标中匹配位置的运算叫做模式匹配(Pattern Matching)。
当然处理这个问题有好几种方法,这里先说明第一种——回溯法
朴素的模式匹配(Naïve Matching):
这是模式匹配中的最简单的一种做法,也是最直观:把pat的字符依次与T中的字符做比较,如果成功则返回pat第0个字符在目标中匹配的位置;如不成功,则将模式pat右移一位,用pat中的字符从新与T中的字符比较。
如此反复,只到下面2种情况结束:一是执行到某一趟的时候,模式的所有字符与目标对应字符相等,则匹配成功;二是pat右移最后可能与T比较的位置,但不是每个字符都能与T匹配,匹配失败。
代码(注:建议多自己亲自动手写,不然会生疏,我这里根据不同的数据结构教材写了3个版本,意思一样):
//北大版
int FindPat( String S, String P,int StartIndex)
...{
int LastIndex = S.size - P.size;
if ( StartIndex > LastIndex)
...{
return (-1);
}
int i = StartIndex ,j =0 ;
while( i< S.size && j< P.size)
...{
if(P.str[j] == S.str[i])
...{
i++;
j++;
}
else
...{
i = i-j+1;
j = 0;
}
}
if ( j >= P.size)
...{
return (i - j);
}
else
return (-1);
}
//清华版
/**//*若在串s(*this)中找不到与串pat匹配的子串, 则函数返回-1,
**否则返回pat在*this中第一次匹配的位置。
*/
int Find(String &pat) const
...{
char *p = pat.ch;
char *s = ch;
int i = 0;
if (*p && *s)
...{
while ( i <= (s.curLen-p.curLen))
...{
if ( *p++ == *s++)
...{
if (!*p)
...{
return i;
}
}
else
...{
i++;
*s = ch + i;
*p = pat.ch;
}
}
}
return (-1);
}
//标准C版:
/**//*这里不匹配的时候返回了NULL,
**否则返回pat在s中第一次匹配的指针
*/
char * Find(char *s, char *p )
...{
for ( int i = 0;(s+i) != NULL ;i++ )
...{
for (int k = i,int j = 0; *(s+k)==*(p+j) && (p+j)!=NULL; k++,j++)
if ((p+j) == NULL)
...{
return s+i;
}
}
return NULL;
}
int FindPat( String S, String P,int StartIndex)
...{
int LastIndex = S.size - P.size;
if ( StartIndex > LastIndex)
...{
return (-1);
}
int i = StartIndex ,j =0 ;
while( i< S.size && j< P.size)
...{
if(P.str[j] == S.str[i])
...{
i++;
j++;
}
else
...{
i = i-j+1;
j = 0;
}
}
if ( j >= P.size)
...{
return (i - j);
}
else
return (-1);
}
//清华版
/**//*若在串s(*this)中找不到与串pat匹配的子串, 则函数返回-1,
**否则返回pat在*this中第一次匹配的位置。
*/
int Find(String &pat) const
...{
char *p = pat.ch;
char *s = ch;
int i = 0;
if (*p && *s)
...{
while ( i <= (s.curLen-p.curLen))
...{
if ( *p++ == *s++)
...{
if (!*p)
...{
return i;
}
}
else
...{
i++;
*s = ch + i;
*p = pat.ch;
}
}
}
return (-1);
}
//标准C版:
/**//*这里不匹配的时候返回了NULL,
**否则返回pat在s中第一次匹配的指针
*/
char * Find(char *s, char *p )
...{
for ( int i = 0;(s+i) != NULL ;i++ )
...{
for (int k = i,int j = 0; *(s+k)==*(p+j) && (p+j)!=NULL; k++,j++)
if ((p+j) == NULL)
...{
return s+i;
}
}
return NULL;
}
这种方法也是带有回溯的模式匹配。
分析复杂度:
设目标T的长度为n,模式pat的长度为m,则最坏情况下模式中的字符比较次数为m,而遍历整个目标串最坏情况是(n-m+1),总的比较次数达到了(n-m+1)*m,而在大多数情况下,n>>m,所以,算法的运行时间为O(n*m)。
个人评价:在你就知道这一种方法的情况下,这也不失为救命稻草。尤其是在模式串很短的时候,目标串不是特别长的时候,这样的算法的复杂度也不会很大,关键是简单。写得匆忙,有错误,请朋友帮忙指出。
参考:北大张铭 数据结构 ;清华殷人昆 数据结构 ;Thomas H. Cormen等 算法导论。
- 字符串模式匹配(Pattern Matching)之一:回溯法
- 2.4.3 模式匹配(Pattern matching)
- 字符串的模式匹配(回溯法)
- 回溯的字符串模式匹配
- 模式匹配(pattern matching)问题:判断一个长为n的字符串X中是否包含常为m的字串Y(m<=n)
- Leetcode Wildcard Matching 字符串*?模式匹配
- Scala新手指南中文版 - 第四篇 Pattern Matching Anonymous Functions(模式匹配匿名函数)
- Scala新手指南中文版 - 第四篇 Pattern Matching Anonymous Functions(模式匹配匿名函数)
- 回溯法字符串匹配算法
- 字符串匹配(string matching)算法之一 (Naive and Rabin_Karp)
- 字符串匹配(string matching)算法之一 (Naive and Rabin_Karp)
- 字符串匹配(String matching)[No. 76]
- 字符串匹配(String Matching)
- 字符串模式匹配之一-------BM & KMP
- 字符串模式匹配之一-------BF & KMP
- 字符串模式匹配算法之一:朴素模式匹配算法
- 通配符匹配字符串 Wildcard Matching
- Wildcard Matching 字符串含?,*匹配
- windows常用命令以及快捷键大全
- 死锁问题
- getwants100
- 命运
- 项目经验-朱国雄
- 字符串模式匹配(Pattern Matching)之一:回溯法
- 几个有用的SAP性能调整的NOTES连接
- 偶然发现网站换肤一招:使页面动态加载不同CSS实现多界面
- 软件开发与文档
- 创新谈-朱国雄
- ActiveX控件用于DHTML开发
- Bad WML syntax. 'Fatal Error. Ln 1, Col 1 The main XML document cannot be empty'.
- RapidShare 真实链接抓取助手
- Stiff asks, great programmers answer