[華爲oj]字符串通配符

該程序只知足匹配第一個相同的字符串,對於出現第二個相同字符的字符串沒法解決。ios

 

#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/22610391app

#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循環,從新開始尋找下一個匹配的地方。spa

(2)應該以匹配字符爲主循環,個人倒是以模式字符串爲主循環。.net

 

結合以上思路,還須要改進,才能運用到當前華爲的oj中。設計

打算在我寫好的程序上進行修改,簡單來講,就是在發現"*"字符串後,加一個for,把後面的都輪一遍,(遞歸),若是for循環一輪後,沒有找到,返回false。blog

 

#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;
}
相關文章
相關標籤/搜索