/*************************************************************************
* Compilation: javac Wildcard.java
* Execution: java Wildcard pattern < wordlist.txt
* Dependencies: In.java
*
* Find all lines in wordlist.txt that match the given pattern by
* simulating a nondeterminstic finite state automaton using an
* Boolean array states[] which records all states that the NFSA
* could be in after reading in a certain number of characters.
*
* Patterns supported
* ------------------------------
* * any zero or more characters
* ? any one character
* c character c
*
*
* Sample execution:
*
* % java Wildcard *wa*t**c*d* < wordlist.txt
* unwatched
* waistcoated
* watchdog
* watched
* watchword
*
* % java Wildcard ?a?e*i*o*u*y < wordlist.txt
* facetiously
*
* % java Wildcard ........................ < wordlist.txt
* formaldehydesulphoxylate
* pathologicopsychological
* scientificophilosophical
* tetraiodophenolphthalein
* thyroparathyroidectomize
*
* Note: not the most efficient algorithm.
*
*************************************************************************/
package com.javaxyq.util;
public class Wildcard {
/***********************************************************************
* Check if pattern string matches text string.
*
* At the beginning of iteration i of main loop
*
* old[j] = true if pattern[0..j] matches text[0..i-1]
*
* By comparing pattern[j] with text[i], the main loop computes
*
* states[j] = true if pattern[0..j] matches text[0..i]
*
***********************************************************************/
static public boolean matches(String pattern, String text) {
// add sentinel so don't need to worry about *'s at end of pattern
text += '\0';
pattern += '\0';
int N = pattern.length();
boolean[] states = new boolean[N+1];
boolean[] old = new boolean[N+1];
old[0] = true;
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
states = new boolean[N+1]; // initialized to false
for (int j = 0; j < N; j++) {
char p = pattern.charAt(j);
// hack to handle *'s that match 0 characters
if (old[j] && (p == '*')) old[j+1] = true;
if (old[j] && (p == c )) states[j+1] = true;
if (old[j] && (p == '?')) states[j+1] = true;
if (old[j] && (p == '*')) states[j] = true;
if (old[j] && (p == '*')) states[j+1] = true;
}
old = states;
}
return states[N];
}
// public static void main(String[] args) {
// String pattern = args[0];
//
// while (!StdIn.isEmpty()) {
// String text = StdIn.readString();
// if (matches(pattern, text))
// System.out.println(text);
// }
// }
}