前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >带有通配符的字符串匹配算法-C/C++

带有通配符的字符串匹配算法-C/C++

作者头像
一见
发布2018-08-07 15:18:35
2.1K0
发布2018-08-07 15:18:35
举报
文章被收录于专栏:蓝天蓝天

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

代码语言:javascript
复制
//方法一,从无通配符到有?再到有*,逐步推进分析
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];  
}  
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2009-01-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档