日前某君给我出了这样一道题目:两个字符串,一个是普通字符串,另一个含有*和?通配符,*代表零个到多个任意字符,?代表一个任意字符,通配符可能多次出现。写一个算法,比较两个字符串是否相等。 我花了四个小时写出两种算法来解决这个问题,简单地测试了一下,好使!

//方法一,从无通配符到有?再到有*,逐步推进分析
char strMatch( const char *str1, const char *str2)
{
int slen1 = strlen(str1);
int slen2 = strlen(str2); //实际使用时根据strl的长度来动态分配表的内存
char matchmap[128][128];
memset(matchmap, 0, 128*128);
matchmap[0][0] = 1;
int i, j, k;
//遍历目标字符串符串
for(i = 1; i<= slen1; ++i)
{
//遍历通配符串
for(j = 1; j<=slen2; ++j)
{
//当前字符之前的字符是否已经得到匹配
if(matchmap[i-1][j-1])
{
//匹配当前字符
if(str1[i-1] == str2[j-1] || str2[j-1] == '?')
{
matchmap[i][j] = 1;
//考虑星号在末尾的情况
if( i == slen1 && j < slen2)
{
for ( k = j+1 ; k <= slen2 ; ++k )
{
if( '*' == str2[k-1])
{
matchmap[i][k] = 1;
}else{
break;
}
}
}
}else if(str2[j-1] == '*')
{
//遇到星号,目标字符串到末尾都能得到匹配
for(k = i-1; k<=slen1; ++k)
{
matchmap[k][j] = 1;
}
}
}
}
//如果当前字符得到了匹配则继续循环,否则匹配失败
for(k = 1; k<=slen2; ++k)
{
if(matchmap[i][k])
{
break;
}
}
if(k>slen2)
{
return 0;
}
}
return matchmap[slen1][slen2];
}
//方法二,分析每个情况。
char strMatch( const char *str1, const char *str2)
{
int slen1 = strlen(str1);
int slen2 = strlen(str2); //实际使用时根据strl的长度来动态分配表的内存
char matchmap[128][128];
memset(matchmap, 0, 128*128);
int i, j, k;
//定义内循环的范围
int lbound = 0;
int upbound = 0;
//遍历目标字符串符串
for(i = 0; i< slen1; ++i)
{
//遍历通配符串
int bMatched = 0;
int upthis = upbound;
for(j = lbound; j<=upthis ; ++j)
{
//匹配当前字符
if(str1[i] == str2[j] || str2[j] == '?')
{
matchmap[i][j] = 1;
if(0 == bMatched)
{
lbound = j+1;
}
upbound = j+1;
bMatched = 1;
if(i == slen1 - 1)
{
//考虑末尾是*的特殊情况
for(k = j+1 ; k < slen2 && '*' == str2[k] ; ++k)
{
matchmap[i][k] = 1;
}
}
}else if(str2[j] == '*')
{
if(0 == bMatched)
{
lbound = j;
}
//遇到星号,目标字符串到末尾都能得到匹配
for(k = i; k< slen1; ++k)
{
matchmap[k][j] = 1;
}
k = j;
while( '*' == str2[++k])
{
matchmap[i][k] = 1;
}
if(str1[i] == str2[k] || str2[k] == '?')
{
matchmap[i][k] = 1;
upbound = k+1;
if(i == slen1 - 1)
{
//考虑末尾是*的特殊情况
for(k = k+1 ; k < slen2 && '*' == str2[k] ; ++k)
{
matchmap[i][k] = 1;
}
}
}else{
upbound = k;
}
bMatched = 1;
}
}
//居然没有匹配到
if(!bMatched )
{
return 0;
}
}
return matchmap[slen1-1][slen2-1];
}

阅读(3050) | 评论(0) | 转发(2) |

评论热议

带有通配符的字符串匹配算法-C/C++的更多相关文章

  1. 字符串匹配算法 - KMP

    前几日在微博上看到一则微博是说面试的时候让面试者写一个很简单的字符串匹配都写不出来,于是我就自己去试了一把.结果写出来的是一个最简单粗暴的算法.这里重新学习了一下几个经典的字符串匹配算法,写篇文章以巩 ...

  2. Boyer-Moore 字符串匹配算法

    字符串匹配问题的形式定义: 文本(Text)是一个长度为 n 的数组 T[1..n]: 模式(Pattern)是一个长度为 m 且 m≤n 的数组 P[1..m]: T 和 P 中的元素都属于有限的字 ...

  3. KMP单模快速字符串匹配算法

    KMP算法是由Knuth,Morris,Pratt共同提出的算法,专门用来解决模式串的匹配,无论目标序列和模式串是什么样子的,都可以在线性时间内完成,而且也不会发生退化,是一个非常优秀的算法,时间复杂 ...

  4. 字符串匹配算法之BF(Brute-Force)算法

    BF(Brute-Force)算法 蛮力搜索,比较简单的一种字符串匹配算法,在处理简单的数据时候就可以用这种算法,完全匹配,就是速度慢啊. 基本思想 从目标串s 的第一个字符起和模式串t的第一个字符进 ...

  5. MVC 中如何将带有标签的字符串转换为HTML 标签 显示出来?

    出现问题的现象:

  6. 【原创】通俗易懂的讲解KMP算法(字符串匹配算法)及代码实现

    一.本文简介 本文的目的是简单明了的讲解KMP算法的思想及实现过程. 网上的文章的确有些杂乱,有的过浅,有的太深,希望本文对初学者是非常友好的. 其实KMP算法有一些改良版,这些是在理解KMP核心思想 ...

  7. 字符串匹配算法——KMP算法学习

    KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...

  8. 4种字符串匹配算法:KMP(下)

    回顾:4种字符串匹配算法:BS朴素 Rabin-karp(上) 4种字符串匹配算法:有限自动机(中) 1.图解 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R ...

  9. 4种字符串匹配算法:BS朴素 Rabin-karp(上)

    字符串的匹配的算法一直都是比较基础的算法,我们本科数据结构就学过了严蔚敏的KMP算法.KMP算法应该是最高效的一种算法,但是确实稍微有点难理解.所以打算,开这个博客,一步步的介绍4种匹配的算法.也是& ...

随机推荐

  1. HDU 5776

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5776 求是否有区间的和是m的倍数 预处理前缀和,一旦有两个数模m的值相同,说明中间一部分连续子列可以组 ...

  2. 查看.Net Framework版本号

    目录 摘要 .NET Framework 的版本 确定计算机上安装的 .NET Framework 版本 补充几个查看.Net Framework版本号 概要 本文描述如何确定计算机上安装的 Micr ...

  3. Linux查看硬件信息(北桥芯片组、南桥、PCI接口、CPU等)

    Linux查看硬件信息(北桥芯片组.南桥.PCI接口.CPU等) Linux查看硬件信息(北桥芯片组.南桥.PCI接口.CPU等) 查看MCH(北桥) 查看ICH(南桥) 查看CPU 查看pci接口设 ...

  4. markdown的学习

    开始 语法 编辑器 sublime配置 图床 体验 开始 昨天晚上加上今天上午,折腾了算是一天的markdown编辑器. 原因是,为了写博客.在博客园写的东西,想法不到简书里,结果发现有部分乱码,以及 ...

  5. immutable学习

    React 做性能优化时有一个避免重复渲染的大招,就是使用 shouldComponentUpdate(),但它默认返回 true,即始终会执行 render() 方法,然后做 Virtual DOM ...

  6. CEF源码编译

    CEF的构造说明:https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding chromium的源码地址:https://c ...

  7. HDU5468(dfs序+容斥原理)

    Puzzled Elena Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  8. 基于OpenCV的火焰检测(二)——RGB颜色判据

    上文跟大家分享了在做火焰检测中常用到的图像预处理方法,从这一篇博文开始,我将向大家介绍如何一步一步地检测出火焰区域.火焰提取要用 到很多判据,今天我要向大家介绍的是最简单的但是很有效的判据--RGB判 ...

  9. 为什么每个浏览器都有Mozilla字样

    你是否好奇标识浏览器身份的User-Agent,为什么每个浏览器都有Mozilla字样?Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 ( ...

  10. 以ed结尾的单词

    1 规则动词词尾加-ed有三种读音 1.1 以清辅音结尾,加-ed    在清辅音后读作[ t ].如:     ask     →  asked                  look   → ...