1 / 1 / 0
Регистрация: 27.04.2020
Сообщений: 59
1

Калькулятор на обратной польской записи

01.06.2020, 15:31. Показов 1245. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет. Пишу калькулятор через обратную польскую запись. Подскажите, как при вводе строки сделать, чтобы можно было разделать символы пробелом? Например при вводе в консоль вместо 2+2*2, вводить 2 + 2 * 2. Ну и также, если не сложно. Подскажите, как сделать так, чтобы можно было считать и двухзначные и трехзначные числа.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <cctype>
 
using namespace std;
 
int getPriority(char s)
{
    switch (s)
    {
    case '(': return 0;
    case ')': return 1;
    case '+': return 2;
    case '-': return 3;
    case '*': return 4;
    case '/': return 4;
    case '^': return 5;
    default: return 6;
    }
}
 
bool IsDelimeter(char c) // проверка на разделитель
{
    if (isspace(c)) return true;
    return false;
}
 
int whickOperation(char s)
{
    switch (s)
    {
    case '+': return 1;
    case '-': return 2;
    case '*': return 3;
    case '/': return 4;
    case '^': return 5;
    default: return 6;
    }
}
 
string getExpr(string arif) // запись выражения в постфиксную форму
{
    stack<char> s;
    string expr;
    for (int i = 0; i < arif.size(); i++)
    {
        if (IsDelimeter(arif[i])) continue;
        if (getPriority(arif[i]) == 6) // если число, записываем в строку
        {
            expr += arif[i];
            continue;
        }
        if (s.empty())
        {
            s.push(arif[i]);
        }
        else
        {
            if (getPriority(arif[i]) == 0) s.push(arif[i]); // если открывающая скобка, кидаем в стек
            if (getPriority(arif[i]) == 1) // если закрывающая скобка, все операции до открывающей записываем в строку
            {
                while (getPriority(s.top()) != 0)
                {
                    expr += s.top();
                    s.pop();
                }
                s.pop();
            }
            if (getPriority(arif[i]) > 1 && getPriority(arif[i]) < 6) // если приоритет предыдущей операции выше, записываем в строку
            {
                if (getPriority(arif[i]) <= getPriority(s.top()))
                {
                    expr += s.top();
                    s.pop();
                }
                s.push(arif[i]);
            }
        }
    }
    while (!s.empty()) // все что осталось в стеке, записываем в строку
    {
        expr += s.top();
        s.pop();
    }
    return expr;
}
 
string inputArif() // Ввод арифметического выражения
{
    string arif;
    cout << "Введите арифметическое выражение -> ";
    cin >> arif;
    return arif;
}
 
double calculate(string expr) // вычисление выражения
{
    stack<char> s;
    double num1 = 0;
    double num2 = 0;
    double result;
    for (int i = 0; i < expr.size(); i++)
    {
        if (getPriority(expr[i]) == 6)
        {
            s.push(expr[i] - '0'); // т.к передается символьное число, надо отнять символьный 0
        }
        else
        {
            num1 = s.top();
            s.pop();
            num2 = s.top();
            s.pop();
            if (whickOperation(expr[i]) == 1) result = num1 + num2;
            if (whickOperation(expr[i]) == 2) result = num1 - num2;
            if (whickOperation(expr[i]) == 3) result = num1 * num2;
            if (whickOperation(expr[i]) == 4) result = num1 / num2;
            if (whickOperation(expr[i]) == 5) result = pow(num1, num2);
            s.push(result);
        }
    }
    return result;
}
 
int main()
{
    setlocale(LC_ALL, "ru");
    string arif = inputArif();
    string expr = getExpr(arif);
    int result = calculate(expr);
    cout << "Ответ: " << result << endl;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.06.2020, 15:31
Ответы с готовыми решениями:

Калькулятор считающий выражения обратной польской записи из файла
Здравствуйте! У меня вот такое задание &quot;Напишите программу, вычисляющую выражение в обратной...

Сложный калькулятор на обратной польской (импиративная парадигма)
Доброго времени суток! Задание, написать сложный калькулятор не используя ООП Сделал на основе...

Написание калькулятора в Обратной Польской Записи
Всем привет, только недавно начал изучать С++ и преподаватель дал задание написать калькулятор в...

Вычисление выражения, использование обратной польской записи
приветствую, люди. можете помочь с реализацией вычисления выражения с помощью обратной польской...

4
4063 / 3317 / 924
Регистрация: 25.03.2012
Сообщений: 12,488
Записей в блоге: 1
01.06.2020, 16:19 2
думаю, если продолжать хранить всё в строках по одному символу, ничего хорошего не выйдет.
Храните в стеке числа и айдишники операций
C++
1
2
3
4
struct {
   int value;
   enum {CONSTANT, PLUS, MINUS, MULT} operation;
}
0
661 / 662 / 106
Регистрация: 29.05.2015
Сообщений: 3,965
01.06.2020, 16:51 3
Написать функцию, которая удалит из строки все пробелы.

Добавлено через 6 минут
Цитата Сообщение от Doppelganker Посмотреть сообщение
Подскажите, как сделать так, чтобы можно было считать и двухзначные и трехзначные числа.
Не сразу отправлять цифру в буфер чисел, а проверить следующий символ. Если там тоже цифра, то "предыдущий * 10 + следующий", и так пока цифры не закончатся.
1
1 / 1 / 0
Регистрация: 27.04.2020
Сообщений: 59
01.06.2020, 17:01  [ТС] 4
Спасибо, так и сделаю
0
0 / 0 / 0
Регистрация: 18.05.2020
Сообщений: 26
10.06.2020, 08:49 5
Написать программу на языке С++ для формирования ОПЗ (Обратной польской записи) и расчета полученного выраже¬ния. Работу программы проверить на конкретном примере

a-b/(c*(d-e)) 2.4 9.5 2.8 6.3 7.2 6.170

mojite ? pamagite
0
10.06.2020, 08:49
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.06.2020, 08:49
Помогаю со студенческими работами здесь

Алгоритм сортировочной станции(вычисление по обратной польской записи).
Всем привет. Есть вот такой код: #include &lt;cstdlib&gt; #include &lt;iostream&gt; #include &lt;fstream&gt;...

Вычислить значение выражения в обратной польской записи с использованием стека
Вычислить значение выражения в обратной польской записи с использованием стека. например 6 2 + = 6...

Построить дерево выражения, записанного в виде обратной польской записи
в текстовом файле дано арифметическое выражение в обратной польской записи. постройте дерево,...

Вычисление выражения записанного в виде обратной польской записи используя бинарное дерево
Всем доброго времени суток. Задача вот такая. Имеется скобочное выражение. Преобразовать его в...

Посчитать значение выражения, записанного в обратной польской нотации
Здравствуйте! Помогите, пожалуйста, разобраться, где ошибка! Задача состоит в том, чтобы...

Калькулятор обратной польской записи
Всем здравствуйте! Необходимо написать программу реализующую калькулятор обратной польской записи,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru