Преобразовать строку логического выражения в древовидную структуру в C # - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь преобразовать строку логических выражений, таких как "a && b || c && d" или "(a && b) || (c && d)", в структуры бинарного дерева:

      ||
    /    \
  &&      && 
 / \     /  \
a   b   c    d

Затем примените поиск в глубину, чтобы пройти их.

Есть ли подходящая библиотека для этого?Я думал об Иронии или Рослине, но не был уверен.

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

На самом деле вы можете использовать библиотеку генератора синтаксических анализаторов, например ANTLR , для достижения вашего результата, но для простой задачи это будет излишним.

Вместо этого вы можете определить свою собственную маленькую грамматику какследует (я использовал «+» вместо «||» и «.» вместо «&&». Замените их символами, а также внесите соответствующие изменения в код синтаксического анализатора с рекурсивным спуском):

S → T '+' S | T
T → F '.' T | F
F → A | '('S')'
A → 'a' | 'b' | 'c' | ... | ɛ

На основе приведенной выше грамматики теперь вы можете легко написать синтаксический анализатор рекурсивного спуска следующим образом (следующий код может быть синтаксически неправильным, просто используйте его в качестве псевдокода):

public Node S(){
        Node  T = T();

        if(inputHasMoreUnseenCharacters() && peekNextCharacterInString().equals("+")){
            eatNextCharacterInString();//eats '+'
            Node S = S();
            return new NodeOR(T, S);
        }

        return T;
    }

public Node T(){
    Node F= F();

    if(inputHasMoreUnseenCharacters() && peekNextCharacterInString().equals(".")){
        eatNextCharacterInString();//eats '.'
        Node T = T();
        return new NodeAND(F, T);
    }

    return F;
}

public Node F(){
    String nextCharacterInput = eatNextCharacterInString();
    Node node = null;
    if(nextCharacterInput.equals("(")){
        //eatNextCharacterInString(); //eats '('
        node = S();
        eatNextCharacterInString(); //eats ')'
    }else{
        node = A(nextCharacterInput);
    }
    return node;
}

public Node A(String nextCharacterInput){
    Node node = null;
    return new NodeSingleValue(nextCharacterInput);
}

Классы NodeOR, NodeAND и NodeSingleValue - это дочерние классы класса Node.Как только вы вызовете метод S (), вы получите корень вашего дерева как объект типа Node.

Для вступления в анализ с рекурсивным спуском эта ссылка может быть полезной.

0 голосов
/ 20 сентября 2018

Я не знаю о библиотеке, но она может быть реализована следующим образом.

То, что вы хотите - это в основном дерево выражений из заданного выражения (его обход в порядке)

Чтобы построить дерево, используйте следующие шаги: Выполните цикл по выражению

  1. Если символ не является оператором, поместите его в стек.

  2. Если символ является оператором, извлеките два операнда, сделайте их дочерними и поместите текущий узел в стек.

  3. В конце концов, единственным элементом в стеке будет ваше дерево.

Пожалуйста, обратитесь по этой ссылке для реализации алгоритма.

...