import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Main {
private static final String STAR
= "*"; private static final String CHAR
= "?";
private final List<String> pattern;
public Main
(final String pattern
) { this.pattern = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for (char c: pattern.toCharArray()) {
switch (c) {
case '*':
token = STAR;
break;
case '?':
token = CHAR;
break;
default:
token = null;
break;
}
if (token == null) {
sb.append(c);
} else {
if (sb.length() > 0) {
this.pattern.add(sb.toString());
sb.setLength(0);
}
this.pattern.add(token);
}
}
if (sb.length() > 0) {
this.pattern.add(sb.toString());
}
ListIterator<String> iter = this.pattern.listIterator();
while (iter.hasNext()) {
if (iter.next() == STAR) {
if (iter.hasNext()) {
if (next == STAR) {
iter.remove();
iter.previous();
} else if (next == CHAR) {
iter.set(STAR);
iter.previous();
iter.previous();
iter.set(CHAR);
iter.next();
}
}
}
}
}
private boolean match
(int pos,
final String str
) { if (pos == pattern.size()) {
return str.isEmpty();
} else {
String token
= pattern.
get(pos
++); if (token == STAR) {
if (pos == pattern.size()) {
return true;
} else {
// this must be a non-wildcard token
token = pattern.get(pos++);
int length = token.length();
for (int idx = str.indexOf(token); idx != -1;
idx = str.indexOf(token, idx + 1))
{
if (match(pos, str.substring(idx + length))) {
return true;
}
}
}
} else if (token == CHAR) {
if (!str.isEmpty()) {
return match(pos, str.substring(1));
}
} else {
if (str.startsWith(token)) {
return match(pos, str.substring(token.length()));
}
}
return false;
}
}
public boolean match
(final String str
) { return match(0, str);
}
@Override
return pattern.toString();
}
public static void main
(final String[] args
) { System.
out.
println(new Main
("hello*world").
match("helloworld")); System.
out.
println(new Main
("hello*world").
match("hello, world")); System.
out.
println(!(new Main
("hello?*world").
match("helloworld"))); System.
out.
println(new Main
("hello?*world").
match("hello world")); System.
out.
println(new Main
("hello*?world").
match("hello, world")); System.
out.
println(!(new Main
("hello*?*?world").
match("hello world"))); System.
out.
println(new Main
("hello*?*?world").
match("hello, world")); System.
out.
println(!(new Main
("hello*??*world").
match("hello, world!"))); System.
out.
println(new Main
("hello*?**?").
match("hello!!")); System.
out.
println(!(new Main
("hello*?**?").
match("hello!"))); System.
out.
println(new Main
("*?*?hello").
match("world, hello")); System.
out.
println(!(new Main
("*?*?hello").
match(" hello"))); System.
out.
println(new Main
("*a").
match("aaa")); }
}
aW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5MaXN0SXRlcmF0b3I7CgpwdWJsaWMgY2xhc3MgTWFpbiB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBUiA9ICIqIjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDSEFSID0gIj8iOwoKICAgIHByaXZhdGUgZmluYWwgTGlzdDxTdHJpbmc+IHBhdHRlcm47CgogICAgcHVibGljIE1haW4oZmluYWwgU3RyaW5nIHBhdHRlcm4pIHsKICAgICAgICB0aGlzLnBhdHRlcm4gPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBmb3IgKGNoYXIgYzogcGF0dGVybi50b0NoYXJBcnJheSgpKSB7CiAgICAgICAgICAgIGZpbmFsIFN0cmluZyB0b2tlbjsKICAgICAgICAgICAgc3dpdGNoIChjKSB7CiAgICAgICAgICAgICAgICBjYXNlICcqJzoKICAgICAgICAgICAgICAgICAgICB0b2tlbiA9IFNUQVI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICc/JzoKICAgICAgICAgICAgICAgICAgICB0b2tlbiA9IENIQVI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHRva2VuID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodG9rZW4gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgc2IuYXBwZW5kKGMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKHNiLmxlbmd0aCgpID4gMCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMucGF0dGVybi5hZGQoc2IudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgc2Iuc2V0TGVuZ3RoKDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5wYXR0ZXJuLmFkZCh0b2tlbik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHNiLmxlbmd0aCgpID4gMCkgewogICAgICAgICAgICB0aGlzLnBhdHRlcm4uYWRkKHNiLnRvU3RyaW5nKCkpOwogICAgICAgIH0KICAgICAgICBMaXN0SXRlcmF0b3I8U3RyaW5nPiBpdGVyID0gdGhpcy5wYXR0ZXJuLmxpc3RJdGVyYXRvcigpOwogICAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICBpZiAoaXRlci5uZXh0KCkgPT0gU1RBUikgewogICAgICAgICAgICAgICAgaWYgKGl0ZXIuaGFzTmV4dCgpKSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5leHQgPSBpdGVyLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCA9PSBTVEFSKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIucHJldmlvdXMoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5leHQgPT0gQ0hBUikgewogICAgICAgICAgICAgICAgICAgICAgICBpdGVyLnNldChTVEFSKTsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlci5wcmV2aW91cygpOwogICAgICAgICAgICAgICAgICAgICAgICBpdGVyLnByZXZpb3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIuc2V0KENIQVIpOwogICAgICAgICAgICAgICAgICAgICAgICBpdGVyLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIG1hdGNoKGludCBwb3MsIGZpbmFsIFN0cmluZyBzdHIpIHsKICAgICAgICBpZiAocG9zID09IHBhdHRlcm4uc2l6ZSgpKSB7CiAgICAgICAgICAgIHJldHVybiBzdHIuaXNFbXB0eSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFN0cmluZyB0b2tlbiA9IHBhdHRlcm4uZ2V0KHBvcysrKTsKICAgICAgICAgICAgaWYgKHRva2VuID09IFNUQVIpIHsKICAgICAgICAgICAgICAgIGlmIChwb3MgPT0gcGF0dGVybi5zaXplKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBtdXN0IGJlIGEgbm9uLXdpbGRjYXJkIHRva2VuCiAgICAgICAgICAgICAgICAgICAgdG9rZW4gPSBwYXR0ZXJuLmdldChwb3MrKyk7CiAgICAgICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IHRva2VuLmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGlkeCA9IHN0ci5pbmRleE9mKHRva2VuKTsgaWR4ICE9IC0xOwogICAgICAgICAgICAgICAgICAgICAgICBpZHggPSBzdHIuaW5kZXhPZih0b2tlbiwgaWR4ICsgMSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2gocG9zLCBzdHIuc3Vic3RyaW5nKGlkeCArIGxlbmd0aCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICh0b2tlbiA9PSBDSEFSKSB7CiAgICAgICAgICAgICAgICBpZiAoIXN0ci5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2gocG9zLCBzdHIuc3Vic3RyaW5nKDEpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChzdHIuc3RhcnRzV2l0aCh0b2tlbikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2gocG9zLCBzdHIuc3Vic3RyaW5nKHRva2VuLmxlbmd0aCgpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChmaW5hbCBTdHJpbmcgc3RyKSB7CiAgICAgICAgcmV0dXJuIG1hdGNoKDAsIHN0cik7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiBwYXR0ZXJuLnRvU3RyaW5nKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgewogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgTWFpbigiaGVsbG8qd29ybGQiKS5tYXRjaCgiaGVsbG93b3JsZCIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obmV3IE1haW4oImhlbGxvKndvcmxkIikubWF0Y2goImhlbGxvLCB3b3JsZCIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIShuZXcgTWFpbigiaGVsbG8/KndvcmxkIikubWF0Y2goImhlbGxvd29ybGQiKSkpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgTWFpbigiaGVsbG8/KndvcmxkIikubWF0Y2goImhlbGxvIHdvcmxkIikpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgTWFpbigiaGVsbG8qP3dvcmxkIikubWF0Y2goImhlbGxvLCB3b3JsZCIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIShuZXcgTWFpbigiaGVsbG8qPyo/d29ybGQiKS5tYXRjaCgiaGVsbG8gd29ybGQiKSkpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgTWFpbigiaGVsbG8qPyo/d29ybGQiKS5tYXRjaCgiaGVsbG8sIHdvcmxkIikpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbighKG5ldyBNYWluKCJoZWxsbyo/Pyp3b3JsZCIpLm1hdGNoKCJoZWxsbywgd29ybGQhIikpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obmV3IE1haW4oImhlbGxvKj8qKj8iKS5tYXRjaCgiaGVsbG8hISIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIShuZXcgTWFpbigiaGVsbG8qPyoqPyIpLm1hdGNoKCJoZWxsbyEiKSkpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgTWFpbigiKj8qP2hlbGxvIikubWF0Y2goIndvcmxkLCBoZWxsbyIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIShuZXcgTWFpbigiKj8qP2hlbGxvIikubWF0Y2goIiBoZWxsbyIpKSk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG5ldyBNYWluKCIqYSIpLm1hdGNoKCJhYWEiKSk7CiAgICB9Cn0=