社区
数据结构与算法
帖子详情
难!带通配符的kmp改进算法?(高手请进)
dg9j
2002-06-15 02:36:12
模式匹配用kmp算法,但如带有通配又如何做?
比如用aaa??*b去匹配,
?是任何字符,*是任何长度的字符串,可能为空。
如何改进KMP算法?
...全文
416
4
打赏
收藏
难!带通配符的kmp改进算法?(高手请进)
模式匹配用kmp算法,但如带有通配又如何做? 比如用aaa??*b去匹配, ?是任何字符,*是任何长度的字符串,可能为空。 如何改进KMP算法?
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
4 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
ninny
2002-06-17
打赏
举报
回复
jx,这段话好面熟:)
one_add_one
2002-06-17
打赏
举报
回复
判定字符正则表达式能否匹配字符串。设字符的正则表达式除一般的普通字符外,还可能有两个特殊字符*和?,其中字符*能匹配任一字符列;字符?可以匹配任一字符;其它字符只能匹配相同的字符。另设被匹配的字符串不包含字符*和字符?。
如字符正则表达式
*A?B*a
能被匹配字符串
abcAAxB12334a
但不能匹配被字符串
aabcAcxB1234a
设待匹配字符串为t,其长度为n(<255);正则表达式为s,其长度为m(<255)。采用动态规划法,用一个两维数组记录各子表达式匹配子字符串的情况,程序引入两维数组a。
1, s[0]至s[j-1]可以匹配t[0]至t[i-1];
a[i][j] = {
0, s[0]至s[j-1]不能匹配t[0]至t[i-1]。
数组a的值可按如下规则确定:
1) 空的正则表达式能匹配空字符串,即a[0][0] = 1;
2) 若s的前j个字符都是字符*,则s[0]至s[j-1]可以匹配空字符串t,即
a[0][j] = 1,(1 <= j <= m && (s[0] = ┅ = s[j-1] = ‘*’)
3) 若s[j-1]为字符*,则让s[j-1]重复0次,它能匹配一个空字符串,即
a[i][j] = s[j-1] == ‘*’ && a[i][j-1]==1
4) 当前s[j-1]仅匹配一个字符,即
a[i][j] = a[i-1][j-1] == 1 &&
(s[j-1]==’*’ || s[j-1] == ‘?’ || s[j-1] == t[i-1]);
5) 当前s[j-1]匹配两个或两个以上连续字符,即因s[j-1]为字符*,还可以多匹配1个字符:
a[i][j] = s[j-1] == ‘*’ && a[i-1][j] == 1。
上述前两条规则用于形成数组a的第0行。后三条用于已知a的前行,根据s和t,确定a的后行。因程序可以逐行计算a, 所以可用两个一维数组实现上述两维数组的要求。记a的前行为first,a的后行为second。
将以上叙述写成算法如下:
{
n = strlen(t); m = strlen(s);
预置second[]不能匹配空串状态;
置空串能匹配空串; /* second[0] = 1 */
当s的前j个字符都是字符*时,设置s[0]至s[j-1]可以匹配空字符串t;
for(i = 1; i <= n; i++) { /* 逐行计算,已知s0至sm-1对t0至ti-2的匹配情况,计算s0至sm-1对t0至ti-1的匹配情况*/
将后行(second)内容移至前一行(first); /* 准备计算新的后行 */
后行新值预置不能匹配任何内容的初值;
for(j = 1; j <= n; j++) /* 计算新行 */
按上述(3)至(5)条件由s[j-1]、t[i-1]和first[]确定second[j];
}
返回判定结果; /* 结果在second[m] */
}
以下是按上述算法编写的匹配函数。
#include <stdio.h>
#include <string.h>
int match(char *t, char *s)
{ int i, j, first[255], second[255], n, m;
n = strlen(t); m = strlen(s);
for(i = 0; i <= m; i++) second[i] = 0;
second[0] = 1;
j = 1;
while(j <= m && s[j-1] == '*') second[j++] = 1;
for(i = 1; i <= n; i++) {
for(j = 0; j <= m; j++)
first[j] = second[j]; /* 将后行内容移至前一行,准备计算新的后行 */
for(j = 0; j <= m; j++) second[j] = 0; /* 后行新值置初值 */
for(j = 1; j <= m; j++) /* 计算新的后行 */
second[j] = ((s[j-1] == '*') &&
(first[j] == 1 || second[j-1] == 1))
|| (((s[j-1] == '*') || (s[j-1] == '?')
||(s[j-1] == t[i-1]))
&& (first[j-1] == 1));
}
return second[m];
}
char t[255], s[255];
void main()
{ char ans;
do {
printf("Enter object string.\n"); gets(t);
printf("Enter pattern string.\n"); gets(s);
printf("%d\n", match(t, s));
printf("Continue?(y/n))\n");
scanf(" %c%*c", &ans);
} while (ans != 'n' && ans != 'N');
}
ffans
2002-06-15
打赏
举报
回复
同意
starfish
2002-06-15
打赏
举报
回复
动态规划,规定x[i]表示字符串x的第i个字符,这里的下标从1开始。定义一个函数Match[i, j],表示特征串x的长度为i的前缀与字符串的s的长度为j的前缀是否匹配。经过分析可以写出如下的递归公式:
Match[i,j] = Match[i-1, j-1], if x[i] = '?'
= Match[i-1, 1..j]中任何一个等于true, if x[i]='*'
= Match[i-1, j-1] and (x[i] = s[j]), if x[i]不是通配符
该递归公式的边界条件是
Match[0,0] = true,
Match[i,0] = Match[i-1,0], if x[i] = '*'
= false, otherwise
根据上面的递归公式和边界条件,很容易写出一个动态规划算法来判断正则表达式x是否匹配字符串s。这个算法的复杂度是O(mn),这里m, n分别是x和s的长度。
经典
算法
回顾之深入理解
KMP
KMP
算法
由Donald E. Knuth、Vaughan R. Pratt和James H. Morris三位计算机科学家于1977年共同提出,是一种高效的字符串匹配
算法
,用于在主文本串中快速查找模式串的出现位置。其核心目标是通过利用已匹配的信息,减少模式串与文本串的重复比较,从而提高匹配效率。本文将对这一
算法
进行重新梳理,并针对next表的构建过程给出简要的证明。
KMP
、Trie树 、AC自动机 ,三大
算法
实现 优雅 过滤敏感词
KMP
、Trie树 、AC自动机 ,三大
算法
实现 优雅 过滤敏感词
极客时间-数据结构与
算法
之美(八)
极客时间-数据结构与
算法
之美(八):
算法
实战
从电影《蝴蝶效应》中学习回溯
算法
的核心思想
点击上方“视学
算法
”,选择加"星标"或“置顶”重磅干货,第一时间送达关注我们丨文末赠书深度优先搜索
算法
利用的是回溯
算法
思想。这个
算法
思想非常简单,但应用却 非常广泛。它除用...
算法
刷题专辑60分版本
用hash表i < 9;= '.') {} } 作者: LeetCode - Solution 链接:https : / / leetcode . cn / problems / valid - sudoku / solution / you - xiao - de - shu - du - by - leetcode - solution - 50 m6 / 来源:力扣( LeetCode )著作权归作者所有。
数据结构与算法
33,028
社区成员
35,336
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章