Я пытаюсь оценить следование из строки
boolean value = evaluate("false || true && true && false || true");
Я должен получить булево значение true
для этого.
Какие-либо идеи о том, как решить эту проблему самым эффективным способом?
String value = ("false || true && true && false || true");
boolean result = false;
for (String conj : value.split("\\|\\|")) {
boolean b = true;
for (String litteral : conj.split("&&"))
b &= Boolean.parseBoolean(litteral.trim());
result |= b;
}
System.out.println(result); // prints true
Вам понадобится небольшая грамматика булевых выражений. Немного рекурсивного разбора должно помочь.
Если вы не знаете, как написать такой парсер, вы можете использовать JavaCC или что-то подобное.
существуют генераторы синтаксического анализатора, для которых вы можете определить грамматику.
Но если бы ты только получил || и && в качестве операторов, а также true и false в качестве значений, вы можете легко сделать это самостоятельно, внедрив очень простой конечный автомат:
1.) Разделите строку на токены
2.) проанализируйте самое левое значение используя Boolean.parseBoolean (токен) и сохраните его значение в некоторой переменной экземпляра (ваше состояние)
3.) объедините вашу переменную экземпляра со следующим логическим токеном, используя данный оператор
4.) Повторяйте шаг 3, пока не закончите через всю строку
Кажется, это работает, хотя я не проверял это тщательно :)
public class BooleanFSParser {
private boolean parse(String data) {
String[] tokens=data.split("\\s");
boolean state=Boolean.parseBoolean(tokens[0]);
for (int i=1;i<(tokens.length / 2) + 1;i=i+2){
if (tokens[i].equals("&&")){
state=state && Boolean.parseBoolean(tokens[i+1]);
}else{
state=state || Boolean.parseBoolean(tokens[i+1]);
}
}
return state;
}
public static void main(String[] args) {
BooleanFSParser parser = new BooleanFSParser();
boolean val = parser.parse("true && true || false");
System.out.println(String.valueOf(val));
}
}
это должно дать вам правильно проанализированное значение, но это станет немного сложнее, если вы, например, разрешите скобки;)
получайте удовольствие и проверьте здесь теорию Конечный_машина
Если единственными операторами являются &&
и ||
, то я думаю, это будет работать:
static boolean eval(String str) {
String s = str.replaceAll("\\s|\\|\\|false|false\\|\\|", "");
return !s.contains("false") || s.contains("||true");
}
Для более сложных выражений я нашел эту библиотеку как раз для этого. Не знаю, насколько она эффективна.