Таблицы истинности

Рейтинг: 0Ответов: 1Опубликовано: 25.04.2023

У меня программа, которая создает таблицы истинности из любого введенного выражения. Оно таблицы то создает, но последний главный столбец всегда 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

Ответы

▲ 0Принят

Метод Boolean.parseBoolean НЕ выполняет разбор и вычисление произвольного логического выражения expression, он возвращает true, только если входная строка равна "true" без учёта регистра.

Документация Boolean::parseBoolean:

public static boolean parseBoolean(String s)
Parses the string argument as a boolean. The boolean returned represents the value true if the string argument is not null and is equal, ignoring case, to the string "true".
Example: Boolean.parseBoolean("True") returns true.
Example: Boolean.parseBoolean("yes") returns false.

Для решения вашей задачи следует воспользоваться какой-либо библиотекой для разбора строк (хотя бы 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);
    }
}