Загрузка данных
#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;
}