题目描述
问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(字符由英文字母和数字0-9组成,不区分大小写。下同)
?:匹配1个字符
输入:
通配符表达式;
一组字符串。
输出:
返回匹配的结果,正确输出true,错误输出false
输入描述:
先输入一个带有通配符的字符串,再输入一个需要匹配的字符串
输出描述:
返回匹配的结果,正确输出true,错误输出false
示例1
输入
te?t*.*
txt12.xls
输出
false
思路:利用正则表达式
import re
while True:
try:
pattern=input().strip()
string=input().strip()
newpattern=pattern.replace('.','\\.').replace('*','[A-Za-z0-9]*').replace('?','.')#新的pattern
if re.match(newpattern,string):
print('true')
else:
print('false')
except:
break
递归解法
递归解法,假设string1是带有通配符的字符串,string2是要匹配的字符串,在第i个字符处有三种
情况:
1、两个字符串都是字母的时候,不相等就是false;
2、遇到?通配符的时候,跳过第i个字符,继续匹配从string1[i+1],string2[i+1]开始匹配;
3、遇到“*”通配符,则遍历后面的字符串,根据情况在进行判断;
def isMatch(string1, string2):
for i in range(len(string1)):
if string1[i].isalpha():
if string1[i] != string2[i]:
return 'false'
else:
if string1[i] == "?":
isMatch(string1[i + 1:], string2[i + 1:])
elif string1[i] == "*":
for j in range(i + 1, len(string1)):
if string1[j] == '?' or string1 == "*":
isMatch(string1[j:], string2[j:])
elif string1[j].isalpha() and string2.isalpha():
if string1[j] == string2[j]:
isMatch(string1[j:], string2[j:])
return 'true'
while True:
try:
string1 = input()
string2 = input()
print(isMatch(string1, string2))
except:
break
JAVA直接利用字符串matches(regex),同样修改regex的表达式为符合原条件的regex
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
while(in.hasNext()){
String reg=in.nextLine();
String str=in.nextLine();
reg=reg.replace(".","\\.");
reg=reg.replace("?","[0-9A-Za-z]?");
reg=reg.replace("*","[0-9A-Za-z]*");
System.out.println(str.matches(reg));
}
}
}
利用动态规划
参考http://www.mamicode.com/info-detail-986984.html
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
while(in.hasNext()){
String reg=in.nextLine();
String str=in.nextLine();
int m=reg.length();
int n=reg.length();
boolean[][] dp=new boolean[m+1][n+1];//默认初始为false;
dp[0][0]=true;
for(int i=1;i<=m;i++){
dp[i][0]=dp[i-1][0]&& (reg.charAt(i-1)=='*');//除第一个字符为*外,其他与str为空匹配都为false
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(reg.charAt(i-1)=='*')//通配符为*,则为0个dp[i-1][j]/多个dp[i][j-1]
dp[i][j]=dp[i-1][j]||dp[i][j-1];
else//其他
dp[i][j]=dp[i-1][j-1]&&(reg.charAt(i-1)==str.charAt(j-1)||reg.charAt(i-1)=='?');
}
}
System.out.println(dp[m][n]);
}
}
}
while True:
try:
pattern=input().strip()
string=input().strip()
m=len(pattern)
n=len(string)
dp=[[False for j in range(n+1)] for i in range(m+1)]
dp[0][0]=True
for i in range(1,m+1):
dp[i][0]=dp[i-1][0] and (pattern[i]=="*")
for i in range(1,m+1):
for j in range(1,n+1):
if pattern[i-1]=="*":
dp[i][j]=dp[i-1][j]or dp[i][j-1]
else:
dp[i][j]=dp[i-1][j-1] and (pattern[i-1]==string[j-1] or pattern[i-1]=="?")
if dp[-1][-1]:
print("true")
else:
print("false")
except:
break