码迷,mamicode.com
首页 > 其他好文 > 详细

[华为oj]字符串通配符

时间:2015-09-08 15:11:09      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:

该程序只满足匹配第一个相同的字符串,对于出现第二个相同字符的字符串无法解决。

 

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int IsMatch(string rule,string sub)
{
	int k=0;
	int c=0;
	while(k<rule.length()&&c<sub.length())
	{
		if(rule[k]==‘?‘)
		{
			++k;
			++c;
			continue;
		}

		if(rule[k]==‘*‘)

		{
			while(rule[k+1]!=sub[c])
			{
				if(sub[c]==‘#‘)
					return 0;
				++c;
			}
				++k;
		}

		if(rule[k]!=sub[c])
			return 0;

	    ++k;
		++c;		
	}

	if(rule[--k]==sub[--c])
		return 1;
	else
		return 0;
}

string ToLower(string ss)
{
	string::iterator itr;
	for(itr=ss.begin();itr!=ss.end();itr++)
	{
		*itr=tolower(*itr);
	}
	return ss;
}

int main()
{
	string rule,sub;
	cin>>rule>>sub;
	rule=ToLower(rule);
	sub=ToLower(sub);
	rule.append("#");
	sub.append("#");
	if(IsMatch(rule,sub))
		cout<<"true"<<endl;
	else
		cout<<"false"<<endl;
}

 

 

在网上搜了下,这段代码是可行的,贴出来进行比较,这段代码是寻找与模式匹配字符串一致的起始位位置,类似于搜索:

http://m.blog.csdn.net/blog/kangroger_11109/22610391

#include<iostream>
using namespace std;
int find(char *substr,int start1,char *str,int start2)
{
	int length1=strlen(substr);//子串长度
	int length2=strlen(str);//母串长度
	int result=-1;//最终要返回的结果
	int current;
	for(int i=start2;i<=length2;i++)//start2为母串搜索的其实位置
	{
		if(i==length2+1)//搜索失败
			return -1;
		result=i;
		current=i;
		for(int k=start1;k<=length1;k++)//start1为子串搜索的其实位置
		{
			if(k==length1-1)
				return result;
			if(substr[k]==str[current]||substr[k]==‘?‘)
			{
				current++;
			}
			else if(substr[k]==‘*‘)//遇到*通配符,代表任何一个或者多个或者0个字符
			{
				if(-1==find(substr,k+1,str,current))
				return -1;
				else return result;
			}
			else break;
		}
	}
}
int main()
{
	char *substr=(char*)malloc(21*sizeof(char));
	char *str=(char*)malloc(21*sizeof(char));
	cin>>substr;
	cin>>str;
	cout<<find(substr,0,str,0);
	return 0;
}

 

(1)我一开始的思路并未使用到递归的思想,而且一找到与第一个与模式字符*后第一个字母匹配的字符后,就不考虑后面还有匹配的情况,导致如果第二个字母不匹配,就直接返回不匹配。在我设计的算法当中,无法规避这个情况。下一段代码在一个for循环当中,把匹配字符的所有字符都遍历一遍。内层for是匹配当前模式字符串,当有匹配字符时,即进入 。一旦某次匹配不成功,即跳出内层for循环。继续外层for循环,重新开始寻找下一个匹配的地方。

(2)应该以匹配字符为主循环,我的却是以模式字符串为主循环。

 

结合以上思路,还需要改进,才能运用到当前华为的oj中。

打算在我写好的程序上进行修改,简单来说,就是在发现"*"字符串后,加一个for,把后面的都轮一遍,(递归),如果for循环一轮后,没有找到,返回false。

 

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int IsMatch(string rule,string sub)
{
	int k=0;
	int c=0;
	while(k<rule.length()&&c<sub.length())
	{
                //改进部分
		if(rule[k]==‘#‘||sub[c]==‘#‘)
		{
			if(rule[k]==‘#‘&& sub[c]==‘#‘)
				return 1;
			else
				return 0;
		}
              //改进部分^

		if(rule[k]==‘?‘)
		{
			++k;
			++c;
			continue;
		}

		if(rule[k]==‘*‘)
		{
                     //改进部分
			for(int n=c;n<sub.length();n++)
			{
				if(IsMatch(rule.substr(k+1),sub.substr(n)))
					return 1;
			}
			return 0;
                   //改进部分^
		}

		if(rule[k]!=sub[c])
			return 0;

	    ++k;
		++c;		
	}
}

string ToLower(string ss)
{
	string::iterator itr;
	for(itr=ss.begin();itr!=ss.end();itr++)
	{
		*itr=tolower(*itr);
	}
	return ss;
}

int main()
{

	string rule,sub;
	cin>>rule>>sub;
	rule=ToLower(rule);
	sub=ToLower(sub);
	rule.append("#");
	sub.append("#");
	if(IsMatch(rule,sub))
		cout<<"true"<<endl;
	else
		cout<<"false"<<endl;
}

  

 

[华为oj]字符串通配符

标签:

原文地址:http://www.cnblogs.com/lsr-flying/p/4786906.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!