Загрузка данных


#include <iostream>
#include <string>
#include <cctype>
using namespace std;

// Узел AST
struct ASTNode {
    string value;        // число, переменная или оператор
    ASTNode* left;
    ASTNode* right;
    
    ASTNode(string val) : value(val), left(NULL), right(NULL) {}
};

class AST {
private:
    ASTNode* root;
    string output;
    
    // Постфиксный обход (левый → правый → корень)
    void postOrder(ASTNode* node) {
        if (!node) return;
        postOrder(node->left);
        postOrder(node->right);
        if (!output.empty()) output += " ";
        output += node->value;
    }
    
    // Освобождение памяти
    void deleteTree(ASTNode* node) {
        if (!node) return;
        deleteTree(node->left);
        deleteTree(node->right);
        delete node;
    }
    
public:
    AST() : root(NULL) {}
    ~AST() { deleteTree(root); }
    
    // Построение AST из инфиксного выражения (упрощенная версия)
    void buildFromInfix(string infix) {
        // Убираем пробелы
        string expr;
        for (char c : infix) {
            if (!isspace(c)) expr += c;
        }
        
        root = parseExpression(expr, 0, expr.length() - 1);
    }
    
    // Парсинг выражения с приоритетами
    ASTNode* parseExpression(string& s, int left, int right) {
        // Поиск оператора с наименьшим приоритетом вне скобок
        int minPriority = 10;
        int minPos = -1;
        int bracketLevel = 0;
        
        for (int i = left; i <= right; i++) {
            if (s[i] == '(') {
                bracketLevel++;
                continue;
            }
            if (s[i] == ')') {
                bracketLevel--;
                continue;
            }
            if (bracketLevel > 0) continue;
            
            int priority;
            if (s[i] == '+' || s[i] == '-') priority = 1;
            else if (s[i] == '*' || s[i] == '/') priority = 2;
            else continue;
            
            if (priority <= minPriority) {
                minPriority = priority;
                minPos = i;
            }
        }
        
        // Если нашли оператор — создаем узел и рекурсивно парсим левую и правую части
        if (minPos != -1) {
            ASTNode* node = new ASTNode(string(1, s[minPos]));
            node->left = parseExpression(s, left, minPos - 1);
            node->right = parseExpression(s, minPos + 1, right);
            return node;
        }
        
        // Убираем внешние скобки
        if (s[left] == '(' && s[right] == ')') {
            return parseExpression(s, left + 1, right - 1);
        }
        
        // Операнд (число или переменная)
        return new ASTNode(s.substr(left, right - left + 1));
    }
    
    // Получение RPN через постфиксный обход
    string getRPN() {
        output.clear();
        postOrder(root);
        return output;
    }
    
    void printTree() {
        printTreeHelper(root, 0);
    }
    
private:
    void printTreeHelper(ASTNode* node, int level) {
        if (!node) return;
        for (int i = 0; i < level; i++) cout << "  ";
        cout << node->value << endl;
        printTreeHelper(node->left, level + 1);
        printTreeHelper(node->right, level + 1);
    }
};

int main() {
    string expression;
    cout << "Введите инфиксное выражение: ";
    getline(cin, expression);
    
    AST ast;
    ast.buildFromInfix(expression);
    
    cout << "\nAST (дерево):" << endl;
    ast.printTree();
    
    string rpn = ast.getRPN();
    cout << "\nПостфиксная запись (RPN): " << rpn << endl;
    
    return 0;
}