Таблицы истинности
У меня программа, которая создает таблицы истинности из любого введенного выражения. Оно таблицы то создает, но последний главный столбец всегда false, помогите разобратся пожалуйста. Код
import java.util.Scanner;
public class TruthTable {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Введите булевое выражение: ");
String expression = scanner.nextLine();
// Получаем список булевых переменных
String[] variables = getVariables(expression);
// Вычисляем количество строк в таблице истинности
int rowCount = (int) Math.pow(2, variables.length);
// Выводим заголовок таблицы
for (String variable: variables) {
System.out.print(variable + "\t\t");
}
System.out.println(expression);
// Выводим строки таблицы истинности
for(int i = 0; i < rowCount; i++) {
boolean[] values = getBooleanValues(i, variables.length);
for (boolean value : values) {
System.out.print(value + "\t");
}
boolean result = evaluateExpression(expression, variables, values);
System.out.println(result);
}
}
// Метод, возвращающий список булевых переменных по выражению
private static String[] getVariables(String expression) {
// Удаляем все символы, кроме букв
expression = expression.replaceAll("[^a-zA-Z]", "");
// Превращаем уникальный набор символов в массив строк
return expression.chars()
.distinct()
.mapToObj(c -> String.valueOf((char) c))
.toArray(String[]::new);
}
// Метод, возвращающий булевые значения для строки таблицы истинности
private static boolean[] getBooleanValues(int row, int variableCount) {
boolean[] values = new boolean[variableCount];
for (int i = 0; i < variableCount; i++) {
values[i] = ((row >> i) & 1) == 1;
}
return values;
}
// Метод, вычисляющий результат булевого выражения для заданных переменных значений
private static boolean evaluateExpression(String expression, String[] variables, boolean[] values) {
for (int i = 0; i < variables.length; i++) {
// Заменяем переменную на ее значение
expression = expression.replaceAll(variables[i], String.valueOf(values[i]));
}
return Boolean.parseBoolean(expression);
}
}
Пример
Введите булевое выражение: (p -> q) && (p != q)
p q (p -> q) && (p != q)
false false false
true false false
false true false
true true false
Правильный вариант
p q (p -> q) && (p != q)
false false false
true false false
false true true
true true false
Ответы (1 шт):
Метод Boolean.parseBoolean НЕ выполняет разбор и вычисление произвольного логического выражения expression, он возвращает true, только если входная строка равна "true" без учёта регистра.
Документация Boolean::parseBoolean:
public static boolean parseBoolean(String s)
Parses the string argument as a boolean. Thebooleanreturned represents the valuetrueif the string argument is not null and is equal, ignoring case, to the string "true".
Example:Boolean.parseBoolean("True")returnstrue.
Example:Boolean.parseBoolean("yes")returnsfalse.
Для решения вашей задачи следует воспользоваться какой-либо библиотекой для разбора строк (хотя бы JS Engine типа Nashorn с функцией eval), но и там операцию импликации -> придётся обрабатывать отдельно.
См. ответ на вопрос Как преобразовать строку с математическим выражением в часть выполняемого кода?
import javax.script.*;
// ...
private static final ScriptEngine engine = new ScriptEngineManager()
.getEngineByName("nashorn");
private static boolean evaluateExpression(String expression, String[] variables, boolean[] values) {
for (int i = 0; i < variables.length; i++) {
// Заменяем переменную на ее значение
expression = expression.replaceAll(variables[i], String.valueOf(values[i]));
}
try {
return (boolean) engine.eval(expression);
} catch (ScriptException screx) { // convert checked exception to Runtime
throw new RuntimeException(screx);
}
}