您的位置:首页 > 其它

44、 Wildcard Matching (Hard)

2016-08-20 22:20 260 查看
Implement wildcard pattern matching with support for 
'?'
 and 
'*'
.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false

题意就是实现智能匹配,?可以匹配任何一个字符,*可以匹配任何数目的任何字符。关键在于对*的处理。这个题是典型的动态规划题,《算法导论》里有,只要注意*在矩阵中的处理即可。自己当时不想用动态规划实现,想到一种自认为比较绝妙的方法,就是把要匹配的字符串按照*分割,然后按照分割次序依次和待匹配的字符串匹配,匹配成功一个就纪录下当前位置,下一个分割的字符串就从当前位置的下一个位置继续开始匹配。如果待匹配的字符串已经到终点而要匹配的分割字符串还没匹配完,就说明匹配失败了。大概是一种贪心的算法思想,而且感觉实现起来不难。结果,我就掉进了一个大坑,各种奇形怪状的测试用例让我对程序的逻辑进行修补,失败了十几次,眼睁睁的看着1807个测试用例的通过个数从500涨到650,再到700、800、1200、1600、1750、1780........最后终于完全AC,这个时候我几乎已经看不懂我的代码了,而且悲剧的是实现时间也只超过了18%的人,如果用动态规划则肯定能超过一半的人。看来用空间换时间还是对的。总之还是要把自己的看不懂但历尽千辛万苦最后还是通过的代码贴出来,动态规划实现的代码网上到处都是,就不贴了。

import java.util.Scanner;

public class Test {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (true) {
String s = in.next();
String p = in.next();
System.out.println(isMatch(s, p));
}
}

public static boolean isMatch(String s, String p) {
if (s.length() == 0 && p.length() == 0) {
return true;
}
char[] a = s.toCharArray();
int skip = 0;

String[] mline = p.split("\\*");

int mlength = 0;
for (int i = 0; i < mline.length; i++) {
if (!mline[i].equals("")) {
mlength++;
}
}

int number = 0;
char[] c = p.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] != '*') {
number++;
}
}

if (number > s.length()) {
return false;
}

if (mline.length == 0) {
return true;
}
if (mlength == 1) {
boolean flag1 = false;
boolean seenflag = false;
boolean fflag = false;
boolean bflag = false;

for (char w : p.toCharArray()) {
if (w == '*') {
flag1 = true;
if (!seenflag) {
fflag = true;
} else {
bflag = true;
}
} else {
seenflag = true;
}
}

if (!flag1 && p.length() != s.length()) {
return false;
}
int snumber = 0;
for (int i = 0; i < mline.length; i++) {
if (mline[i].length() > 0) {
snumber = i;
}
}

char[] bb = mline[snumber].toCharArray();

boolean flag = false;
if (fflag && bflag) {

for (int i = 0; i <= a.length - bb.length; i++) {
for (int j = 0; j < bb.l
4000
ength; j++) {
if (a[i + j] != bb[j] && bb[j] != '?') {
break;
} else {
if (j == bb.length - 1) {
flag = true;
break;
}
}
}
}

}

else if (fflag && !bflag) {
int i = a.length - 1;
int j = bb.length - 1;
while (j >= 0 && i >= 0 && (a[i] == bb[j] || bb[j] == '?')) {
if (j == 0) {
flag = true;
}
i--;
j--;
}
} else if (!fflag && bflag) {

System.out.println("4");
for (int i = 0; i < bb.length; i++) {
if (bb[i] == a[i] || bb[i] == '?') {
if (i == bb.length - 1) {
flag = true;
break;
}
} else {
break;
}
}
} else {
for (int i = 0; i < bb.length; i++) {
if (bb[i] == a[i] || bb[i] == '?') {
if (i == bb.length - 1 && i == a.length - 1) {
flag = true;
break;
}
} else {
break;
}
}
}

if (!flag) {
return false;
}

if (flag) {
return true;
}

}

// *分割的第一个字符串和最后一个字符串也必须要判断。
for (int i = 0; i < mline.length; i++) {
System.out.println("skip:" + skip);
char[] b = mline[i].toCharArray();
if (b.length == 0) {
continue;
}
if (i == 0) {
System.out.println("0判断");
boolean temp = false;
for (int k = 0; k < b.length; k++) {
System.out.println("K判断"+k+" ak:"+a[k]+" bk:"+b[k]);
if (b[k] == a[k] || b[k] == '?') {

if (k == b.length - 1) {
temp = true;
}
}
else{
break;
}
}
if (!temp) {
return false;
}

}

else if (i == mline.length - 1) {
if (!p.substring(p.length() - 1, p.length()).equals("*")) {
System.out.println("!!*");
boolean temp = false;
for (int k = 0; k < b.length; k++) {
if ((b[b.length - 1 - k] == a[a.length - 1 - k])
|| b[b.length - 1 - k] == '?') {
if (k == b.length - 1) {
temp = true;
}
} else {
break;
}
}
System.out.println("skiplalal: "+skip+" "+s.length());
if (!temp || skip ==s.length()||(skip<s.length()&&skip+b.length>s.length())) {
return false;
} else {
System.out.println("lallaalwwww");
return true;
}
} else {
System.out.println("*");
// 最后一个是*,跳跃skip
for (int k = skip; k < s.length(); k++) {
boolean flag = false;
for (int j = 0; j < b.length; j++) {
if (j + k < a.length) {
if (b[j] == a[j + k] || b[j] == '?') {
if (j == b.length - 1) {
flag = true;
}
} else {
break;
}
} else {
return false;
}
}
if (flag) {
skip = k;
// System.out.println("wen");
return true;
}
}
return false;

}
}

boolean matchflag = false;
if (skip < s.length()) {
for (int k = skip; k < s.length(); k++) {
// System.out.println("k:" + k);
boolean flag = false;
for (int j = 0; j < b.length; j++) {
if (j + k < a.length) {
if (b[j] == a[j + k] || b[j] == '?') {
if (j == b.length - 1) {
flag = true;
matchflag = true;
}
} else {
break;
}
} else {
return false;
}
}
if (flag) {
skip += (k - skip + b.length);
break;
}
}
if(!matchflag){
return false;
}

} else {
return false;
}

}

/*
mississippi
m*i*si*si*si*pi
*/

return false;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: