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


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

struct tstk {
    double inf;
    tstk *a;
};

struct tstkStr {
    char inf[100];
    tstkStr *a;
};

tstk *AddStack(tstk *sp, double inf) {
    tstk *spt = new tstk;
    spt->inf = inf;
    spt->a = sp;
    return spt;
}

tstk *ReadStack(tstk *sp, double &inf) {
    tstk *spt = sp;
    inf = sp->inf;
    sp = sp->a;
    delete spt;
    return sp;
}

tstkStr *AddStackStr(tstkStr *sp, char *inf) {
    tstkStr *spt = new tstkStr;
    strcpy(spt->inf, inf);
    spt->a = sp;
    return spt;
}

tstkStr *ReadStackStr(tstkStr *sp, char *inf) {
    tstkStr *spt = sp;
    strcpy(inf, sp->inf);
    sp = sp->a;
    delete spt;
    return sp;
}

int isNumber(char *s) {
    int i = 0;
    if (s[0] == '-') i++;
    int dot = 0;
    for (; s[i]; i++) {
        if (s[i] == '.') { dot++; if (dot > 1) return 0; }
        else if (s[i] < '0' || s[i] > '9') return 0;
    }
    return 1;
}

int isOperator(char c) {
    return (c == '+' || c == '-' || c == '*' || c == '/');
}

// Вычисление RPN (числового, без переменных)
double calcRPN(char *str) {
    tstk *sp = NULL;
    char *tok = strtok(str, " ");
    double a, b;
    
    while (tok) {
        if (isNumber(tok)) {
            sp = AddStack(sp, atof(tok));
        } else if (strlen(tok) == 1 && isOperator(tok[0])) {
            sp = ReadStack(sp, b);
            sp = ReadStack(sp, a);
            switch (tok[0]) {
                case '+': sp = AddStack(sp, a + b); break;
                case '-': sp = AddStack(sp, a - b); break;
                case '*': sp = AddStack(sp, a * b); break;
                case '/': sp = AddStack(sp, a / b); break;
            }
        }
        tok = strtok(NULL, " ");
    }
    double res;
    sp = ReadStack(sp, res);
    return res;
}

// Проверка, состоит ли фрагмент только из чисел и операторов
int isConstantFragment(char *str) {
    char copy[100];
    strcpy(copy, str);
    char *tok = strtok(copy, " ");
    while (tok) {
        if (!isNumber(tok) && !(strlen(tok) == 1 && isOperator(tok[0]))) {
            return 0;
        }
        tok = strtok(NULL, " ");
    }
    return 1;
}

// Оптимизация RPN
void OptimizeRPN(char *in, char *out) {
    tstkStr *sp = NULL;
    char *tok = strtok(in, " ");
    
    while (tok) {
        // Если токен - число или переменная
        if (isNumber(tok) || (strlen(tok) == 1 && !isOperator(tok[0]))) {
            sp = AddStackStr(sp, tok);
        }
        // Если токен - оператор
        else if (strlen(tok) == 1 && isOperator(tok[0])) {
            // Берем два верхних элемента из стека
            char b[100], a[100];
            sp = ReadStackStr(sp, b);
            sp = ReadStackStr(sp, a);
            
            // Составляем фрагмент "a b оператор"
            char fragment[300];
            sprintf(fragment, "%s %s %s", a, b, tok);
            
            // Проверяем, можно ли вычислить этот фрагмент
            if (isNumber(a) && isNumber(b)) {
                // Оба числа - вычисляем
                char copy[300];
                strcpy(copy, fragment);
                double res = calcRPN(copy);
                char resStr[100];
                if (res == (int)res) sprintf(resStr, "%d", (int)res);
                else sprintf(resStr, "%g", res);
                sp = AddStackStr(sp, resStr);
            } else {
                // Нельзя вычислить - возвращаем обратно
                sp = AddStackStr(sp, a);
                sp = AddStackStr(sp, b);
                sp = AddStackStr(sp, tok);
            }
        }
        tok = strtok(NULL, " ");
    }
    
    // Собираем результат
    char temp[100][100];
    int cnt = 0;
    while (sp) {
        sp = ReadStackStr(sp, temp[cnt++]);
    }
    
    out[0] = '\0';
    for (int i = cnt - 1; i >= 0; i--) {
        strcat(out, temp[i]);
        if (i > 0) strcat(out, " ");
    }
}

int main() {
    char rpn[200], optimized[200];
    
    cout << "Vvedite RPN virazhenie: ";
    cin.getline(rpn, 200);
    
    char copy[200];
    strcpy(copy, rpn);
    
    OptimizeRPN(copy, optimized);
    
    cout << "Optimizirovannoe: " << optimized << endl;
    
    return 0;
}