Given an arbitrary number of TextField inputs (t1, t2, t3, ...) and a custom boolean string input from a JtextArea, I need to check if lines in a file match the custom boolean expression. It needs to support nested parentheses.
Example:
User enters "str1" into t1 , "str2" into t2, "str3" into t3, "str4" into t4, "str5" into t5.
User enters the following into the JTextArea for the custom boolean:
"not ((t1 and not t3) or (t4 and t2)) or t5"
Then based on these inputs, I must filter a file and return lines in the file that match the custom boolean based on a "contains" relationship (e.g. "t1 and not t3" means a line must contain the string t1 and not contain the string t3).
For example a file with the following two lines:
str 5
str4 str2
The filter would only return str5 because it is the only line that matches the custom boolean.
I am having trouble even getting started. I have tried to think of a recursive solution but couldn't come up with anything. Also I tried non-recursive solutions but can't come up with anything either.
There is also the problem of the end result boolean needing to take in a parameter (each line in the file). I thought of maybe producing a sequence of operations to perform rather than a boolean that somehow takes in a parameter. But I can't figure out how to get this sequence in the first place.
Here is what I have now. It is very bad and I am thinking of scrapping this approach.
public class CustomInputParser {
private ArrayList<String> pairs;
private String inp;
private HashMap<Integer,String> atomMap;
public CustomInputParser() {
this.pairs = null;
this.inp = "";
this.atomMap = new HashMap<Integer,String>();
}
public void findAtoms() {
int i = 0;
for(String s : this.pairs) {
String[] indices = s.split(",");
int begin = Integer.valueOf(indices[0]);
int end = Integer.valueOf(indices[1]);
if(!inp.substring(begin+1, end).contains("(")) {
this.pairs.set(i, this.pairs.get(i) + ",@");
}
i++;
}
}
public void computeAtoms() {
int i = 0;
for(String s : this.pairs) {
if(s.contains(",@")) {
String[] indices = s.split(",");
int begin = Integer.valueOf(indices[0]);
int end = Integer.valueOf(indices[1]);
//this.pairs.set(i,this.pairs.get(i).replace(",a", ""));
this.pairs.set(i, this.pairs.get(i) + ","+inp.substring(begin+1, end));
this.atomMap.put(begin,this.pairs.get(i).split(",")[3]+"#"+String.valueOf(end));
}
i++;
}
System.out.println(this.pairs.toString());
System.out.println(this.atomMap.toString());
}
public void replaceAtoms() {
int i = 0;
for(String s : this.pairs) {
if(!(s.contains("o") || s.contains("a") || s.contains("n"))) {
String[] indices = s.split(",");
int begin = Integer.valueOf(indices[0])+1;
int end = Integer.valueOf(indices[1]);
for(int j = begin; j < end; j++) {
if(inp.charAt(j) == '(') {
if(atomMap.containsKey(j)) {
this.pairs.set(i, this.pairs.get(i) + ","+j+"#"+atomMap.get(j).split("#")[1]+">"+atomMap.get(j).split("#")[0]);
}
else {
this.pairs.set(i,"!"+ this.pairs.get(i));
}
}
}
}
i++;
}
System.out.println(this.pairs.toString());
}
public ArrayList<String> getPairs(String str){
this.inp = str;
ArrayList<String> res = new ArrayList<String>();
char[] arr = str.toCharArray();
Stack<Integer> s = new Stack<Integer>();
for(int i = 0; i < arr.length; i++) {
if(arr[i] == '(') {
s.push(i);
}
if(arr[i] == ')') {
if(s.empty()) {
return null;
}
else {
Integer start = s.pop();
Integer end = Integer.valueOf(i);
res.add(start.toString() + "," + end.toString());
}
}
}
if(!s.empty()) {
return null;
}
this.pairs = res;
return res;
}
public static void main(String[] args) {
String x = "((not t1 and ((not t2 or t4) or (t3 or t4))) or (t5 and not t6)) and t7";
x = x.replace("not", "n").replace("and","a").replace("or", "o").replace("t", "").replace(" ", "");
System.out.println(x);
CustomInputParser c = new CustomInputParser();
System.out.println(c.getPairs(x).toString());
c.findAtoms();
c.computeAtoms();
c.replaceAtoms();
}
}