Skip to main content
Code Review

Return to Answer

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link
revise the code. use matches() instead of find()
Source Link
rolfl
  • 98.1k
  • 17
  • 219
  • 419
public List<List<SymbolChoice>> forceFitRegex(final String regex) {
 return forceFitRegex(regex, false);
}
public List<List<SymbolChoice>> forceFitRegex(final String regex, boolean debug) {
 Objects.requireNonNull(regex, "regex");
 final List<Symbol> symbols = getSymbols();
 SymbolChoice[][] options = new SymbolChoice[symbols.size()][];
 int pos = 0;
 int combinations = 1;
 final SymbolChoice[] emptyChoice = new SymbolChoice[0];
 for (Symbol symbol : getSymbols()) {
 options[pos] = symbol.getSymbolChoices().toArray(emptyChoice);
 combinations *= options[pos].length;
 pos++;
 }
 Pattern pattern = Pattern.compile(regex);
 int[] stack = new int[options.length];
 int[] sbsize = new int[options.length + 1];
 List<List<SymbolChoice>> listOfSymbolChoices = new ArrayList<List<SymbolChoice>>();
 StringBuilder sb = new StringBuilder(stack.length);
 int depth = 0;
 int testcnt = 0;
 while (depth >= 0) {
 if (depthstack[depth] ==>= optionsoptions[depth].length) {
 Matcher matcherstack[depth] = pattern.matcher(sb);0;
 testcnt++;depth--;
 if (matcher.matches()depth >= 0) {
 // we havesb.setLength(sbsize[depth]);
 a viable answer here, we can report it....
 stack[depth]++;
 List<SymbolChoice> match = new ArrayList<>(stack.length);}
 } else {
 for (int i = 0; i < stacksb.length; i++append(options[depth][stack[depth]].symbol.value) {;
 Matcher matcher = matchpattern.addmatcher(options[i][stack[i]]sb);
 }testcnt++;
 boolean found = listOfSymbolChoicesmatcher.addmatches(match);
 }
 if (depth == options.length - 1) {
 depth--;
 if sb.setLength(sbsize[depth]found); {
 stack[depth]++;
 }// elsewe ifhave (stack[depth]a >=viable options[depth].length)answer {
here, we can report it....
 stack[depth] = 0;
 List<SymbolChoice> match = depth--new ArrayList<>(stack.length);
 if for (depthint >=i 0= 0; i < stack.length; i++) {
 sb match.setLengthadd(sbsize[depth]options[i][stack[i]]);
 stack[depth]++;
 }
 }
 } else { listOfSymbolChoices.add(match);
 sb.append(options[depth][stack[depth]].symbol.value); }
 Matcher matcher = pattern sb.matchersetLength(sbsbsize[depth]);
 testcnt++; stack[depth]++;
 } else if (matcher.find()found || matcher.hitEnd()) {
 // we have a viable answer here, we can descend....
 depth++;
 sbsize[depth] = sb.length();
 } else {
 // nothing viable down here....
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 }
 }
 }
 if (debug) {
 System.out.println("Combinations: " + combinations + " actual tests " + testcnt);
 }
 return listOfSymbolChoices;
}
public List<List<SymbolChoice>> forceFitRegex(final String regex) {
 return forceFitRegex(regex, false);
}
public List<List<SymbolChoice>> forceFitRegex(final String regex, boolean debug) {
 Objects.requireNonNull(regex, "regex");
 final List<Symbol> symbols = getSymbols();
 SymbolChoice[][] options = new SymbolChoice[symbols.size()][];
 int pos = 0;
 int combinations = 1;
 final SymbolChoice[] emptyChoice = new SymbolChoice[0];
 for (Symbol symbol : getSymbols()) {
 options[pos] = symbol.getSymbolChoices().toArray(emptyChoice);
 combinations *= options[pos].length;
 pos++;
 }
 Pattern pattern = Pattern.compile(regex);
 int[] stack = new int[options.length];
 int[] sbsize = new int[options.length + 1];
 List<List<SymbolChoice>> listOfSymbolChoices = new ArrayList<List<SymbolChoice>>();
 StringBuilder sb = new StringBuilder(stack.length);
 int depth = 0;
 int testcnt = 0;
 while (depth >= 0) {
 if (depth == options.length) {
 Matcher matcher = pattern.matcher(sb);
 testcnt++;
 if (matcher.matches()) {
 // we have a viable answer here, we can report it....
 List<SymbolChoice> match = new ArrayList<>(stack.length);
 for (int i = 0; i < stack.length; i++) {
 match.add(options[i][stack[i]]);
 }
 listOfSymbolChoices.add(match);
 }
  depth--;
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 } else if (stack[depth] >= options[depth].length) {
 stack[depth] = 0;
 depth--;
 if (depth >= 0) {
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 }
 } else {
 sb.append(options[depth][stack[depth]].symbol.value);
 Matcher matcher = pattern.matcher(sb);
 testcnt++;
 if (matcher.find() || matcher.hitEnd()) {
 // we have a viable answer here, we can descend....
 depth++;
 sbsize[depth] = sb.length();
 } else {
 // nothing viable down here....
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 }
 }
 }
public List<List<SymbolChoice>> forceFitRegex(final String regex) {
 return forceFitRegex(regex, false);
}
public List<List<SymbolChoice>> forceFitRegex(final String regex, boolean debug) {
 Objects.requireNonNull(regex, "regex");
 final List<Symbol> symbols = getSymbols();
 SymbolChoice[][] options = new SymbolChoice[symbols.size()][];
 int pos = 0;
 int combinations = 1;
 final SymbolChoice[] emptyChoice = new SymbolChoice[0];
 for (Symbol symbol : getSymbols()) {
 options[pos] = symbol.getSymbolChoices().toArray(emptyChoice);
 combinations *= options[pos].length;
 pos++;
 }
 Pattern pattern = Pattern.compile(regex);
 int[] stack = new int[options.length];
 int[] sbsize = new int[options.length + 1];
 List<List<SymbolChoice>> listOfSymbolChoices = new ArrayList<List<SymbolChoice>>();
 StringBuilder sb = new StringBuilder(stack.length);
 int depth = 0;
 int testcnt = 0;
 while (depth >= 0) {
 if (stack[depth] >= options[depth].length) {
 stack[depth] = 0;
 depth--;
 if (depth >= 0) {
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 }
 } else {
 sb.append(options[depth][stack[depth]].symbol.value);
 Matcher matcher = pattern.matcher(sb);
 testcnt++;
 boolean found = matcher.matches();
 if (depth == options.length - 1) {
 if (found) {
 // we have a viable answer here, we can report it....
 List<SymbolChoice> match = new ArrayList<>(stack.length);
 for (int i = 0; i < stack.length; i++) {
  match.add(options[i][stack[i]]);
 }
  listOfSymbolChoices.add(match);
  }
  sb.setLength(sbsize[depth]);
  stack[depth]++;
 } else if (found || matcher.hitEnd()) {
 // we have a viable answer here, we can descend....
 depth++;
 sbsize[depth] = sb.length();
 } else {
 // nothing viable down here....
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 }
 }
 }
 if (debug) {
 System.out.println("Combinations: " + combinations + " actual tests " + testcnt);
 }
 return listOfSymbolChoices;
}
added 2925 characters in body
Source Link
rolfl
  • 98.1k
  • 17
  • 219
  • 419


Edit: Based on the hitEnd() hint from maaartinus

if you are reading this, then consider upvoting his answer...

I have played with the code, and it is significantly faster... Consider this revised method (I won't pretend it is easy to read... - it is basically a state machine, though). I have put a test up on Ideone that processes 380M combinations in less than 2 seconds.....

public List<List<SymbolChoice>> forceFitRegex(final String regex) {
 return forceFitRegex(regex, false);
}
public List<List<SymbolChoice>> forceFitRegex(final String regex, boolean debug) {
 Objects.requireNonNull(regex, "regex");
 final List<Symbol> symbols = getSymbols();
 SymbolChoice[][] options = new SymbolChoice[symbols.size()][];
 int pos = 0;
 int combinations = 1;
 final SymbolChoice[] emptyChoice = new SymbolChoice[0];
 for (Symbol symbol : getSymbols()) {
 options[pos] = symbol.getSymbolChoices().toArray(emptyChoice);
 combinations *= options[pos].length;
 pos++;
 }
 Pattern pattern = Pattern.compile(regex);
 int[] stack = new int[options.length];
 int[] sbsize = new int[options.length + 1];
 List<List<SymbolChoice>> listOfSymbolChoices = new ArrayList<List<SymbolChoice>>();
 StringBuilder sb = new StringBuilder(stack.length);
 int depth = 0;
 int testcnt = 0;
 while (depth >= 0) {
 if (depth == options.length) {
 Matcher matcher = pattern.matcher(sb);
 testcnt++;
 if (matcher.matches()) {
 // we have a viable answer here, we can report it....
 List<SymbolChoice> match = new ArrayList<>(stack.length);
 for (int i = 0; i < stack.length; i++) {
 match.add(options[i][stack[i]]);
 }
 listOfSymbolChoices.add(match);
 }
 depth--;
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 } else if (stack[depth] >= options[depth].length) {
 stack[depth] = 0;
 depth--;
 if (depth >= 0) {
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 }
 } else {
 sb.append(options[depth][stack[depth]].symbol.value);
 Matcher matcher = pattern.matcher(sb);
 testcnt++;
 if (matcher.find() || matcher.hitEnd()) {
 // we have a viable answer here, we can descend....
 depth++;
 sbsize[depth] = sb.length();
 } else {
 // nothing viable down here....
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 }
 }
 }


Edit: Based on the hitEnd() hint from maaartinus

if you are reading this, then consider upvoting his answer...

I have played with the code, and it is significantly faster... Consider this revised method (I won't pretend it is easy to read... - it is basically a state machine, though). I have put a test up on Ideone that processes 380M combinations in less than 2 seconds.....

public List<List<SymbolChoice>> forceFitRegex(final String regex) {
 return forceFitRegex(regex, false);
}
public List<List<SymbolChoice>> forceFitRegex(final String regex, boolean debug) {
 Objects.requireNonNull(regex, "regex");
 final List<Symbol> symbols = getSymbols();
 SymbolChoice[][] options = new SymbolChoice[symbols.size()][];
 int pos = 0;
 int combinations = 1;
 final SymbolChoice[] emptyChoice = new SymbolChoice[0];
 for (Symbol symbol : getSymbols()) {
 options[pos] = symbol.getSymbolChoices().toArray(emptyChoice);
 combinations *= options[pos].length;
 pos++;
 }
 Pattern pattern = Pattern.compile(regex);
 int[] stack = new int[options.length];
 int[] sbsize = new int[options.length + 1];
 List<List<SymbolChoice>> listOfSymbolChoices = new ArrayList<List<SymbolChoice>>();
 StringBuilder sb = new StringBuilder(stack.length);
 int depth = 0;
 int testcnt = 0;
 while (depth >= 0) {
 if (depth == options.length) {
 Matcher matcher = pattern.matcher(sb);
 testcnt++;
 if (matcher.matches()) {
 // we have a viable answer here, we can report it....
 List<SymbolChoice> match = new ArrayList<>(stack.length);
 for (int i = 0; i < stack.length; i++) {
 match.add(options[i][stack[i]]);
 }
 listOfSymbolChoices.add(match);
 }
 depth--;
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 } else if (stack[depth] >= options[depth].length) {
 stack[depth] = 0;
 depth--;
 if (depth >= 0) {
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 }
 } else {
 sb.append(options[depth][stack[depth]].symbol.value);
 Matcher matcher = pattern.matcher(sb);
 testcnt++;
 if (matcher.find() || matcher.hitEnd()) {
 // we have a viable answer here, we can descend....
 depth++;
 sbsize[depth] = sb.length();
 } else {
 // nothing viable down here....
 sb.setLength(sbsize[depth]);
 stack[depth]++;
 }
 }
 }
Source Link
rolfl
  • 98.1k
  • 17
  • 219
  • 419
Loading
lang-java

AltStyle によって変換されたページ (->オリジナル) /