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


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <map>

using namespace std;

// Структура стека из шаблона лабораторной работы
struct tstk
{
    double inf;
    tstk *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; 
}

int priority(char ch) // Вычисление приоритета операций
{
    switch (ch)
    {
        case '(': case ')': return 0;
        case '+': case '-': return 1;
        case '*': case '/': return 2;
        default: return -1;
    }
}

// Карта для хранения значений переменных
map<string, double> variables;

void AddPostFix(char *strin, char *strout)
{
    tstk *sp = NULL;
    int n = 0;
    char ch;
    double inf;

    for(unsigned int i = 0; i < strlen(strin); i++)
    {
        ch = strin[i];

        // Если это операнд (буква или цифра) - собираем многосимвольный токен
        if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) 
        { 
            string var_name = "";
            // Читаем всё слово или число до конца
            while (i < strlen(strin) && ((strin[i] >= 'A' && strin[i] <= 'Z') || 
                                         (strin[i] >= 'a' && strin[i] <= 'z') || 
                                         (strin[i] >= '0' && strin[i] <= '9'))) 
            {
                var_name += strin[i];
                strout[n++] = strin[i];
                i++;
            }
            strout[n++] = ' '; // Разделяем элементы пробелом
            i--; // Компенсируем инкремент в цикле for

            // Если это переменная (начинается с буквы), добавляем в словарь
            if ((var_name[0] >= 'A' && var_name[0] <= 'Z') || (var_name[0] >= 'a' && var_name[0] <= 'z')) {
                variables[var_name] = 0.0; // Регистрируем переменную
            }
            continue; 
        }

        // Если стек пуст или найдена открывающая скобка
        if (sp == NULL || ch == '(') { 
            sp = AddStack(sp, ch); 
            continue; 
        }

        // Если найдена закрывающая скобка
        if (ch == ')')
        {
            while (sp->inf != '(')
            {
                sp = ReadStack(sp, inf);
                strout[n++] = (char)inf;
                strout[n++] = ' ';
            }
            sp = ReadStack(sp, inf); // Удаление открывающей скобки
            continue;
        }

        // Если операция
        int pr = priority(ch);
        while (sp != NULL && priority((char)sp->inf) >= pr)
        {
            sp = ReadStack(sp, inf);
            strout[n++] = (char)inf;
            strout[n++] = ' ';
        }
        sp = AddStack(sp, ch);
    }

    // Выталкиваем оставшиеся операции
    while (sp != NULL)
    {
        sp = ReadStack(sp, inf);
        strout[n++] = (char)inf;
        strout[n++] = ' ';
    }
    strout[n++] = '\0';
}

double rasAV(char *str)
{
    tstk *sp = NULL;
    char token[100];
    int ti = 0;
    double inf, inf1, inf2;

    for (unsigned int i = 0; i <= strlen(str); i++)
    {
        char ch = str[i];
        
        // Разделяем строку по пробелам на отдельные токены
        if (ch == ' ' || ch == '\0') 
        {
            if (ti > 0) 
            {
                token[ti] = '\0';
                
                // Если токен начинается с цифры - это число
                if (token[0] >= '0' && token[0] <= '9') {
                    sp = AddStack(sp, atof(token));
                } 
                // Если с буквы - это переменная
                else if ((token[0] >= 'A' && token[0] <= 'Z') || (token[0] >= 'a' && token[0] <= 'z')) {
                    sp = AddStack(sp, variables[string(token)]);
                } 
                // Иначе - это операция
                else {
                    sp = ReadStack(sp, inf2);
                    sp = ReadStack(sp, inf1);
                    switch (token[0])
                    {
                        case '+': sp = AddStack(sp, inf1 + inf2); break;
                        case '-': sp = AddStack(sp, inf1 - inf2); break;
                        case '*': sp = AddStack(sp, inf1 * inf2); break;
                        case '/': sp = AddStack(sp, inf1 / inf2); break;
                    }
                }
                ti = 0;
            }
        } 
        else 
        {
            token[ti++] = ch;
        }
    }
    sp = ReadStack(sp, inf);
    return inf;
}

int main()
{
    char str[200], strp[200];

    cout << "Vvedite viragenie bez probelov (naprimer: (abc+12)*def):" << endl;
    cin >> str;

    // Очищаем словарь переменных перед новым запуском
    variables.clear(); 

    // Преобразование в ОПЗ (заодно соберет все найденные переменные)
    AddPostFix(str, strp);
    
    cout << "OPZ: " << strp << endl;

    // Если в выражении были найдены переменные, запрашиваем их значения
    if (!variables.empty()) {
        cout << "Vvedite znacheniya dlya peremennih:" << endl;
        for (auto const& [key, val] : variables) {
            cout << key << " = ";
            cin >> variables[key];
        }
    }

    // Вычисление результата
    double s = rasAV(strp);
    cout << "Res=" << s << endl;

    return 0;
}