Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
1 / 1 / 0
Регистрация: 16.08.2021
Сообщений: 4

Калькулятор без скобок. Как можно сделать код проще?

16.08.2021, 01:11. Показов 3491. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
написал свой первый калькулятор на несколько действий подряд
Буду признателен ,если вы накидаете вариантов ,как можно сделать код проще(сто процентов это возможно тк я зеленый новичек)

ссылка на проект:https://onlinegdb.com/IuKFLbrFy
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#include <iostream>
#include<string>
#include<string.h>
using namespace std;
string flg(string str)
{
    string chisl1, chisl2;
    int znak;
    if (str.find('+') != (-1))
    {
        znak = 1;
        chisl1 = str.substr(0, str.find('+'));
        chisl2 = str.substr(str.find('+') + 1, str.length());
    }
    if (str.find('-') != (-1))
    {
        znak = 2;
        chisl1 = str.substr(0, str.find('-'));
        chisl2 = str.substr(str.find('-') + 1, str.length());
    }
    if (str.find('*') != (-1))
    {
        znak = 3;
        chisl1 = str.substr(0, str.find('*'));
        chisl2 = str.substr(str.find('*') + 1, str.length());
    }
    if (str.find('/') != (-1))
    {
        znak = 4;
        chisl1 = str.substr(0, str.find('/'));
        chisl2 = str.substr(str.find('/') + 1, str.length());
    }
    double chisll1, chisll2;
    chisll1 = atof(chisl1.c_str());
    chisll2 = atof(chisl2.c_str());
    switch (znak)
    {
    case 1:
        return to_string(chisll1 + chisll2);
        break;
    case 2:
        return to_string(chisll1 - chisll2);
        break;
    case 3:
        return to_string(chisll1 * chisll2);
        break;
    case 4:
        return to_string(chisll1 / chisll2);
        break;
    }
}
int main()
{
    setlocale(LC_ALL, "Russian");
    string str,chisl1,chisl2,strstr,strstrstr,gl,wp;
    char a;
    int N = 0,znak,help,k,k1;
    cout << "Введите выражение:" << endl;
    cin >> str;
    while (str.find('+') != (-1) || str.find('-') != (-1) || str.find('*') != (-1) || str.find('/') != (-1))
    {
        if (str.find('*') != (-1))
        {
            k = 0;
            strstr = str;
            strstr = strstr.substr(0, strstr.find('*'));
            for (int i = 0; i < (strstr.length()) / 2 ; i++)
            {
                a = strstr[i];
                strstr[i] = strstr[strstr.length() - 1 - i];
                strstr[strstr.length() - 1 - i] = a;
            }
            while (k<strstr.length())
            {
                k++;
                if (strstr[k] == '/' || strstr[k] == '+' || strstr[k] == '-' || strstr[k] == '*')
                {
                    break;
                }
            }
            k1 = 0;
            strstr = str;
            strstr = strstr.substr(strstr.find('*') + 1, strstr.length());
            while (k1 < strstr.length())
            {
                k1++;
                if (strstr[k1] == '/' || strstr[k1] == '+' || strstr[k1] == '-' || strstr[k1] == '*')
                {
                    break;
                }
            }
            strstr[0] = 0;
            strstr = str.substr(0, str.find('*') - k) + flg(str.substr(str.find('*') - k, k + 1 + k1)) + str.substr(str.find('*') + k1 + 1, str.length());
            str = strstr;
        }
        if (str.find('/') != (-1))
        {
            k = 0;
            strstr = str;
            strstr = strstr.substr(0, strstr.find('/'));
            for (int i = 0; i < (strstr.length()) / 2; i++)
            {
                a = strstr[i];
                strstr[i] = strstr[strstr.length() - 1 - i];
                strstr[strstr.length() - 1 - i] = a;
            }
            while (k < strstr.length())
            {
                k++;
                if (strstr[k] == '/' || strstr[k] == '+' || strstr[k] == '-' || strstr[k] == '*')
                {
                    break;
                }
            }
            k1 = 0;
            strstr = str;
            strstr = strstr.substr(strstr.find('/') + 1, strstr.length());
            while (k1 < strstr.length())
            {
                k1++;
                if (strstr[k1] == '/' || strstr[k1] == '+' || strstr[k1] == '-' || strstr[k1] == '*')
                {
                    break;
                }
            }
            strstr[0] = 0;
            strstr = str.substr(0, str.find('/') - k) + flg(str.substr(str.find('/') - k, k + 1 + k1)) + str.substr(str.find('/') + k1 + 1, str.length());
            str = strstr;
        }
        if (str.find('+') != (-1))
        {
            k = 0;
            strstr = str;
            strstr = strstr.substr(0, strstr.find('+'));
            for (int i = 0; i < (strstr.length()) / 2; i++)
            {
                a = strstr[i];
                strstr[i] = strstr[strstr.length() - 1 - i];
                strstr[strstr.length() - 1 - i] = a;
            }
            while (k < strstr.length())
            {
                k++;
                if (strstr[k] == '/' || strstr[k] == '+' || strstr[k] == '-' || strstr[k] == '*')
                {
                    break;
                }
            }
            k1 = 0;
            strstr = str;
            strstr = strstr.substr(strstr.find('+') + 1, strstr.length());
            while (k1 < strstr.length())
            {
                k1++;
                if (strstr[k1] == '/' || strstr[k1] == '+' || strstr[k1] == '-' || strstr[k1] == '*')
                {
                    break;
                }
            }
            strstr[0] = 0;
            strstr = str.substr(0, str.find('+') - k) + flg(str.substr(str.find('+') - k, k + 1 + k1)) + str.substr(str.find('+') + k1 + 1, str.length());
            str = strstr;
        }
        if (str.find('-') != (-1))
        {
            k = 0;
            strstr = str;
            strstr = strstr.substr(0, strstr.find('-'));
            for (int i = 0; i < (strstr.length()) / 2; i++)
            {
                a = strstr[i];
                strstr[i] = strstr[strstr.length() - 1 - i];
                strstr[strstr.length() - 1 - i] = a;
            }
            while (k < strstr.length())
            {
                k++;
                if (strstr[k] == '/' || strstr[k] == '+' || strstr[k] == '-' || strstr[k] == '*')
                {
                    break;
                }
            }
            k1 = 0;
            strstr = str;
            strstr = strstr.substr(strstr.find('-') + 1, strstr.length());
            while (k1 < strstr.length())
            {
                k1++;
                if (strstr[k1] == '/' || strstr[k1] == '+' || strstr[k1] == '-' || strstr[k1] == '*')
                {
                    break;
                }
            }
            strstr[0] = 0;
            strstr = str.substr(0, str.find('-') - k) + flg(str.substr(str.find('-') - k, k + 1 + k1)) + str.substr(str.find('-') + k1 + 1, str.length());
            str = strstr;
        }
    }
    cout << "=" << str;
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.08.2021, 01:11
Ответы с готовыми решениями:

Страуструп. Сортировка трех чисел .Как сделать проще код без циклов и массивов?
Напишите программу. предлагающую пользователю ввести три целых числа, а затем выводит их в порядке возрастания, разделяя запятыми ....

Можно ли для C++ сделать подсвечивание скобок? Как комментировать код в C++?
Предположим есть блок у которого есть границы выглядит это так {блок}, когда ставишь курсор внутрь этих скобок загорается 2ая фигурная...

Оператор switch, можно ли сделать код проще?
Дана задача посчитать гласные в тексте введенном с клавиатуры, вопрос ниже... #include &lt;iostream&gt; #include &lt;string&gt; ...

25
1620 / 1185 / 553
Регистрация: 08.01.2012
Сообщений: 4,564
17.08.2021, 05:47
Студворк — интернет-сервис помощи студентам
180 строк
Миниатюры
Калькулятор без скобок. Как можно сделать код проще?  
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38228 / 21160 / 4314
Регистрация: 12.02.2012
Сообщений: 34,773
Записей в блоге: 14
17.08.2021, 08:44
Сам нашел в своей реализации ошибку... Заодно и унарные операции:

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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#include <iostream>
#include <string>
#include <stack>
#include <cmath>
 
using namespace std;
 
// string -> double
 
double s2d(string s)
{
      int i,f=0;
      char a;
      double ce=0,fr=0,pw=1.0;
      for (i=0; i<s.size(); i++)
      {
          a=s[i];
          if (a=='.') 
             f=1;
          else
             if (f==0)
                ce=ce*10.0+(double)(a-'0');
             else
             {
                fr=fr*10.0+(double)(a-'0');
                pw=pw*10.0;
             }        
      }
      return ce+fr/pw;
}
 
// Проверка: символ a присутствует в строке s
 
int isIn(char a, string s)
{
    int i,n=s.size();
    for (i=0; i<n; i++)
        if (s[i]==a) return i;
    return -1;
}    
 
string * parse(string formula_i)
{
       string formula;
       int n;
       string tmp;                    // это аккумулятор
       char a;                        // это очередной символ
       int i,ptr;                     // ptr - номер очередной позиции в res
       int p;
 
       // Унарный плюс и минус       
 
       if (formula_i[0]=='-' || formula_i[0]=='+')
          formula="0"+formula_i;
       else
          formula=formula_i;
          
       while(1)
       {
           p=formula.find("(-");
           if (p==string::npos) break;
           formula.replace(p,2,"(0-");
       }
 
       while(1)
       {
           p=formula.find("(+");
           if (p==string::npos) break;
           formula.replace(p,2,"(0+");
       }
             
       n=formula.size();
       string *res = new string[n+1]; // один лишний элемент - на случай, если каждый символ есть лексема.
       
       ptr=0;
       tmp="";
       
       for (i=0; i<=n; i++) res[i]=""; // чистка res
       
       for (i=0; i<n; i++)             // цикл по символам формулы
       {
           a=formula[i];               // очередной символ
           if (isIn(a,"+-*/^()") >= 0) // это разделитель???
           {
                                       // да                    
             if (tmp.size()>0) res[ptr++]=tmp; // если аккумулятор непуст - сбросим его в res
             res[ptr++]=string(1,a);           // а в следующую позицию - найденный разделитель
             tmp="";                           // аккумулятор чистим                 
           }
           else                        // это не разделитель
           {
             tmp=tmp+string(1,a);      // приклеим его к аккумулятору
           }  
       }
       // если в аккумуляторе что-то осталось - сбросим
       if (tmp.size()>0) res[ptr++]=tmp;
       return res;
}
 
int prty(char op)
{
    switch (op)
    {
       case '(':
            return 0;
       case '+':
       case '-':
            return 1;
       case '*':
       case '/':
            return 2;
       case '^':
            return 3;
       default:
            return -1;        
    }
}            
 
double exec(char op, double a1, double a2)
{
    double r;   
    switch (op)
    {
        case '+':
             r=a1+a2;
             return r;
        case '-':
             r=a1-a2;
             return r;
        case '*':
             r=a1*a2;
             return r;
        case '/':
             r=a1/a2;
             return r;
        case '^':
             r=pow(a1,a2);
             return r;
    }            
}                        
 
double calc(string formula)
{
    stack <double> s1;
    stack <char>   s2;
 
    int i,ilex=0,p1,p2,pp1;
    double v,a1,a2,r;
    string curr; 
 
    string *lex=parse(formula);
 
    while(lex[ilex] != "")
    {
       curr=lex[ilex++];  
       
       if (curr[0]>='0' && curr[0]<='9')    // Число - в s1
       {
          v=s2d(curr);
          s1.push(v);
       }
       else                                 // разделитель
       {                 
          if ((curr[0]=='(') || s2.empty()) // левая скобка или первая операция 
          {    
             s2.push(curr[0]);
          }
          else 
          {
             if (curr[0]==')')              // опустошение до открывающей скобки
             {
                while(1)   
                {
                  if (s2.top()=='(')         
                  {
                     s2.pop();
                     break;
                   }                        
                   a2=s1.top();
                   s1.pop();
                   a1=s1.top();
                   s1.pop();
                   r=exec(s2.top(),a1,a2);
                   s1.push(r);
                   s2.pop(); 
                } 
             }
             else 
             {
                p1=prty(s2.top());          // приоритет вершины стека
                p2=prty(curr[0]);           // приоритет новой операции
             
                if (p2>p1)                  // более приоритетная операция 
                {
                   s2.push(curr[0]);
                }
                else
                {
                   pp1=p2;
                   while (1)
                   {
                     a2=s1.top();
                     s1.pop();
                     a1=s1.top();
                     s1.pop();
                     r=exec(s2.top(),a1,a2);
                     s1.push(r);
                     s2.pop(); 
                     if (s2.empty())
                     {
                        s2.push(curr[0]);
                        break;
                     }
                     p1=prty(s2.top());
                     if (p1==pp1) continue;
                     s2.push(curr[0]);
                     break;
                   } 
                }
             }   
          }             
       }      
    }           
 
    // Финишное опустошение стека
     
    while(1)
    {
       if (s2.empty())  break;
       a2=s1.top();
       s1.pop();
       a1=s1.top();
       s1.pop();
       r=exec(s2.top(),a1,a2);
       s1.push(r);
       s2.pop(); 
    }
 
    delete [] lex;
     
    return s1.top();
}
 
int main(int argc, char *argv[])
{
    string formula="(-34+7)*3+5*(3+8)";
 
    double r=calc(formula);
 
    cout << r << endl;
    
}
Добавлено через 10 минут
Renji, отличный код! Рекурсивный спуск изящнее Брауэра-Замельзона.
0
Заблокирован
17.08.2021, 11:00
MansMI, то что на скрине реально работает? можно потестить? и почему нет LogA(B) и Ctg?
0
1620 / 1185 / 553
Регистрация: 08.01.2012
Сообщений: 4,564
17.08.2021, 14:47
Цитата Сообщение от RahatLukum Посмотреть сообщение
нет LogA(B) и Ctg
за грамматику и 5%0+ln(-2)/acos(8) сами отвечаете
Миниатюры
Калькулятор без скобок. Как можно сделать код проще?  
Вложения
Тип файла: rar Calculator.rar (17.8 Кб, 5 просмотров)
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
17.08.2021, 21:45
вообще не могу понять как в 21 веке еще кто то качество кода считает его строками , ммм, печалька....
Цитата Сообщение от Catstail Посмотреть сообщение
Рекурсивный спуск изящнее
и да, этот подход мне нравится больше всего, и возможностей у него тоже много, так же как и есть ограничения.
Так что конкретная реализация "калькулятора" зависит от цели/задачи , а не от предпочтения программиста, имхо.
1
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38228 / 21160 / 4314
Регистрация: 12.02.2012
Сообщений: 34,773
Записей в блоге: 14
18.08.2021, 08:21
SmallEvil, ну, короткий код привлекателен... Как стихи! Хотя краткость сама по себе может сослужить и плохую службу. Вот впечатляющий пример. Задача: "Дано целое i. Если значение i равно 2, сделать его равным 1. А если равно 1, сделать равным 2"

Каноническое решение:

C
1
2
3
4
5
6
   if (i==1)
      i=2;
   else if (i==2)
      i=1;
   else
      printf("bad data!");
Краткое решение (которое дал бы математик):

C
1
    i=3-i;
Обычно его критикуют за то, что оно не анализирует исходные данные (считая их идеальными). Но, на мой взгляд, главный недостаток здесь - в невозможности соотнести решение и постановку. Если любому вменяемому программисту дать первое решение и спросить, что оно делает, то он в ответ просто воспроизведет ТЗ. А если дать второе, то ответ будет "отнимает от тройки значение i"
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.08.2021, 08:21

можно сделать данную программу проще?как можно примитивней
Var F,x: real; Function ArcCos(z:Real):Real; begin if Round(z*10000000)=10000000 then ArcCos:=0 else if...

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

Как можно оптимизировать код? Код считывает кол-во скобок
s = input() s = cheked = set() ans = 0 L = len(s) for l in range(L+1 if L % 2 else L, 1, -2): for i in range(L-l+1): ...

Сравнивание массивов.Как можно сделать проще ?
Реализовал метод richEquals,который принимает два параметра array1 {Array} array2 {Array}.И возвращает булен равны ли массивы array1 и...

Как проще можно очистить коллекцию List в зависимости от предиката (без присваивания)?
Например есть List из объектов &quot;Человек&quot;. Нужно очистить от всех объектов у которых возраст &lt; 18. Без присваивания имел ввиду...


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

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru