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

//方法一,从无通配符到有?再到有*,逐步推进分析
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. Communication System(动态规划)

    个人心得:百度推荐的简单DP题,自己做了下发现真得水,看了题解发现他们的思维真得比我好太多太多, 这是一段漫长的锻炼路呀. 关于这道题,我最开始用DP的思路,找子状态,发现自己根本就不会找DP状态数组 ...

  2. Js中的prototype的用法二

    用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...

  3. python exec内置表达式--exec()

    exec obj功能: exec 执行储存在字符串或文件中的Python语句,相比于 eval,exec可以执行更复杂的 Python 代码.obj 是 要执行的表达式.exec 返回值永远为 Non ...

  4. MyBatis定制SQL集中特殊的处理方式

    举例说明: 1.查询 姓为林的数据  LIKE 3种 Select * from sys_user where user_name like '林%' 关于结果集合多个参数传递数据 特殊字符的处理

  5. (转)详解C#中的反射

    本文转载自:http://blog.csdn.net/educast/article/details/2894892 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到 ...

  6. PAT L3-008. 喊山(BFS)C4 初赛30分

    喊山(30 分) 喊山,是人双手围在嘴边成喇叭状,对着远方高山发出“喂—喂喂—喂喂喂……”的呼唤.呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的“讯号”,达到声讯传递交流的目的. ...

  7. Java-API-Package:javax.annotation

    ylbtech-Java-API-Package:javax.annotation 1.返回顶部 1. Package javax.annotation Enum Summary Resource.A ...

  8. Sass和Less、Stylus的转译和语法(1)

    四.Sass.LESS和Stylus转译成CSSSass.LESS和Stylus源文件(除了LESS源文件在客户端下运行之外)都不能直接被浏览器直接识别,这样一来,要正常的使用这些源文 件,就需要将其 ...

  9. HTML5的离线应用

    参考:有趣的HTML5:离线存储——segmentfault HTML5的离线存储 简介 HTML5提供了很多新的功能以及相应的接口,离线存储就是其中的一个.通过浏览器访问Web App需要联网发送请 ...

  10. 2016全国大学生信息安全竞赛(Misc)

    你好,i春秋: 关注i春秋公众微信号,然后发送CTF,机器人会问星期几,按实回答,然后发送你好,机器人会回复你好,然后随便发几句,机器人会问是否愿意陪他聊天,回复不愿意,机器人就会发flag kill ...