java - How to get all possible combinations of substrings? -
i have string of following structure: a1(n1,n2,n3)p4(o3,o5)y1.
how combinations? rule options inside parenthesis should not go together. example output should be:
a1n1p4o3y1, a1n2p4o3y1, a1n3p4o3y1, a1n1p4o5y1, a1n2p4o5y1, a1n3p4o5y1.
there can parenthesis, can without it. example:
n3p5(l1,l2)q1, output should be:
n3p5l1q1, n3p5l2q1.
anyone elegant solution?
the main idea transform string input stringtemplate holds parts, can single string or group of strings.
for each part, iterator created. while iterator can go next, update string array holds current part values , reset iterators of parts come before part changed. feel free clear repeated code , add nested groups support , syntax verifications if needed.
private static stringtemplate parse(string string) { list<stringpart> parts = new arraylist<stringpart>(); boolean insidegroup = false; stringbuilder currenttoken = new stringbuilder(); list<literalpart> groupparts = new arraylist<literalpart>(); (int = 0; < string.length(); i++) { char ch = string.charat(i); if (ch == '(') { if (currenttoken.length() != 0) { parts.add(new literalpart(currenttoken.tostring())); currenttoken.delete(0, currenttoken.length()); } insidegroup = true; } else if (ch == ')') { if (insidegroup) { if (currenttoken.length() != 0) { groupparts.add(new literalpart(currenttoken.tostring())); currenttoken.delete(0, currenttoken.length()); } parts.add(new compositepart(groupparts)); groupparts.clear(); insidegroup = false; } else { currenttoken.append(ch); } } else if (ch == ',') { if (insidegroup) { if (currenttoken.length() != 0) { groupparts.add(new literalpart(currenttoken.tostring())); currenttoken.delete(0, currenttoken.length()); } } else { currenttoken.append(ch); } } else { currenttoken.append(ch); } } if (currenttoken.length() != 0) { parts.add(new literalpart(currenttoken.tostring())); currenttoken.delete(0, currenttoken.length()); } return new stringtemplate(parts); } private static final class stringtemplate { private final list<stringpart> parts; public stringtemplate(list<stringpart> parts) { this.parts = parts; } public list<string> getcombinations() { list<iterator<string>> iterators = new arraylist<iterator<string>>(parts.size()); (stringpart part : parts) { iterators.add(part.getstrings().iterator()); } string[] tojoin = new string[iterators.size()]; list<string> combinations = new arraylist<string>(); int iteratorthatadvanced; int maxiteratorthatadvanced = integer.min_value; boolean first = true; (;;) { iteratorthatadvanced = -1; (int = 0; < iterators.size(); i++) { iterator<string> iterator = iterators.get(i); if (first || iterator.hasnext()) { string value = iterator.next(); tojoin[i] = value; iteratorthatadvanced = i; if (!first && >= maxiteratorthatadvanced) { maxiteratorthatadvanced = i; break; } } } if (iteratorthatadvanced < 0) { break; } if (!first) { (int = 0; < iteratorthatadvanced; i++) { iterator<string> iterator = parts.get(i).getstrings().iterator(); iterators.set(i, iterator); tojoin[i] = iterator.next(); } } combinations.add(join(tojoin)); first = false; } return combinations; } } private static string join(string[] strings) { stringbuilder builder = new stringbuilder(); (string string : strings) { builder.append(string); } return builder.tostring(); } private static abstract class stringpart { abstract list<string> getstrings(); } private static final class literalpart extends stringpart { private final string literal; public literalpart(string literal) { this.literal = literal; } @override list<string> getstrings() { return collections.singletonlist(literal); } } private static final class compositepart extends stringpart { private final list<literalpart> parts; public compositepart(list<literalpart> parts) { this.parts = new arraylist<literalpart>(parts); } @override list<string> getstrings() { list<string> strings = new arraylist<string>(parts.size()); (literalpart part : parts) { strings.add(part.literal); } return strings; } }
example:
public static void main(string[] args) { stringtemplate template = parse("a1(n1,n2,n3)p4(o3,o5)y1"); (string combination : template.getcombinations()) { system.out.println(combination); } template = parse("n3p5(l1,l2)q1"); (string combination : template.getcombinations()) { system.out.println(combination); } }
Comments
Post a Comment