Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.64/14: Рейтинг темы: голосов - 14, средняя оценка - 4.64
1 / 1 / 0
Регистрация: 25.12.2018
Сообщений: 12
1

Калькулятор с новыми операциями

25.08.2019, 02:14. Показов 2935. Ответов 11
Метки нет (Все метки)

Всем привет, моя первая тема на форуме, готов к советам по оформлению.
Суть задачи:
Для чисел a и b определим следующие операции: a~b = 2*a – b; a#b = b + a.
Операция “#” приоритетнее, чем “~”, т.е. a~b#c = a~(b#c). Операции с одинаковым приоритетом всегда выполняются слева направо. Нужно написать программу, вычисляющую значение арифметического выражения, состоящего только из целых чисел и операций “#” и “~”. Ввод и вывод через файл (input.txt и output.txt). Вводные данные всегда корректны, без пробелов.

Код для меня не так важен, как понять построение алгоритма.

Сам вижу только вариант через vector <char>, циклом идти по вектору, удалять # и добавлять ответ, пока их не останется, потом тоже самое с ~. Для этого нужно будет постоянно переводить несколько char символов в одно int число, если операция не подходит по приоритету- обновлять счётчики, вообщем настолько громоздко и страшно, что в голове не укладывается.

Сам сделал только ввод из файла в строку, все дальнейшие попытки приводили к тильту.
Заранее спасибо.


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <fstream>
#include <string>
 
using namespace std;
 
int main() {
    string s;
    ifstream file;
    file.open("input.txt");
    if (!file.is_open()) {
        cout << "the file cannot be opened, put the file in the project folder" << endl;
        return -1;
    }
    else {
        getline(file, s);
        //
    }
    //
    return 0;
}
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.08.2019, 02:14
Ответы с готовыми решениями:

Калькулятор с несколькими операциями
Привет всем гуру программирования и новичкам в этом деле! Нужна ваша помощь, совет или критика....

Работа с несколькими операциями калькулятор
Помогите пожалуйста, сделать так, чтобы калькулятор считал несколько действий. Например 1+2+1, не...

Калькулятор. Вычисление выражений с несколькими операциями
Пытаюсь сделать возможным вычисление значения выражения типа 12+23+334-21, нажав «=» только один...

Калькулятор на php: как правильнее работать с арифметическими операциями
Скачал методичку ШАГа, прошел переменные, математические функции, массивы, строки, вызов функций. ...

11
170 / 122 / 61
Регистрация: 06.02.2015
Сообщений: 300
25.08.2019, 09:17 2
Лучший ответ Сообщение было отмечено cleanbrain как решение

Решение

Не решение, а пища для размышлений
1. Преобразуем строку (Обратная польская запись)
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
#include <iostream>
#include <string.h> 
#include <stack>
#include <sstream>
 
using namespace std;
 
int priority_operations(char c){ //приоритет операций
    if (c == '#'){
        return 3;
    }
    else if (c == '~') {
        return 2;
    }
    else {
        return -1;
    }
}
 
string infixToPostfix(string s){ 
    std::stack<char> st;
    st.push('N');
    int l = s.length();
    string ns;
 
    for (int i = 0; i < l; i++){ 
        if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= '0' && s[i] <= '9')) {
            ns += s[i];
            ns = ns + " ";
        }
 
        else if (s[i] == '(')
            st.push('(');
 
        else if (s[i] == ')'){
            while (st.top() != 'N' && st.top() != '('){
                char c = st.top();
                st.pop();
                ns += c;
            }
            if (st.top() == '('){
                char c = st.top();
                st.pop();
            }
        }
 
        else {
            while (st.top() != 'N' && priority_operations(s[i]) <= priority_operations(st.top())){
                char c = st.top();
                st.pop();
                ns += c;
                ns = ns + " ";
            }
            st.push(s[i]);
        }
 
    }
    
    while (st.top() != 'N'){
        char c = st.top();
        st.pop();
        ns += c;
    }
 
    return ns;
}
 
 
double solver(string str1) {
    stack<double>stack;
    double first, second;
    istringstream is(str1);
 
    for (; is >> str1;){
        if (str1.compare("#")==0) {
            first = stack.top();
            stack.pop();
            second = stack.top();
            stack.pop();
            stack.push(2*second - first);
        }
 
        else if (str1.compare("~")==0) {
            first = stack.top();
            stack.pop();
            second = stack.top();
            stack.pop();
            stack.push(second + first);
        }
        
        else {
            stack.push(strtof(str1.c_str(), NULL));
        }
    }
 
    return stack.top();
}
 
int main(){
    string exp = "4#1";
    string res=infixToPostfix(exp);
    cout << res << endl;
    cout << solver(res) << endl;
    system("pause");
    return 0;
}
взято отсюда https://stackoverflow.com/ques... calculator
1
812 / 500 / 210
Регистрация: 19.01.2019
Сообщений: 1,196
26.08.2019, 03:51 3
Лучший ответ Сообщение было отмечено cleanbrain как решение

Решение

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
#include <stdio.h>
#include <string.h>
 
size_t parse(char* begin, char* end, int* dest) {
    int a, b;
    char* it;
    sscanf(begin, "%d", &a);
    for (it = begin; it != end; ++it) {
        if (*it == '~') {
            *dest++ = a;
            return parse(it + 1, end, dest) + 1;
        }
        if (*it == '#') {
            sscanf(it + 1, "%d", &b);
            a += b;
        }
    }
    *dest = a;
    return 1;
}
 
int calc(char* begin, char* end) {
    int buff[BUFSIZ];
    size_t size = parse(begin, end, buff);
    int i, res = buff[0];
    for (i = 1; i < size; ++i) {
        res = res * 2 - buff[i];
    }
    return res;
}
main

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
int main()
{
    {
        char ch[] = "2~4";
        printf("%d\n", calc(ch, ch + sizeof(ch) - 1));
    }
    {
        char ch[] = "2#-2";
        printf("%d\n", calc(ch, ch + sizeof(ch) - 1));
    }
    {
        char ch[] = "2~2#2";
        printf("%d\n", calc(ch, ch + sizeof(ch) - 1));
    }
    {
        char ch[] = "2~0~8";
        printf("%d\n", calc(ch, ch + sizeof(ch) - 1));
    }
    {
        char ch[] = "2~-6~20";
        printf("%d\n", calc(ch, ch + sizeof(ch) - 1));
    }
    {
        char ch[] = "2~1#1~2#2";
        printf("%d\n", calc(ch, ch + sizeof(ch) - 1));
    }
    {
        char ch[] = "2~1#2#1~2~6~15#-35";
        printf("%d\n", calc(ch, ch + sizeof(ch) - 1));
    }
 
    return 0;
}
1
1 / 1 / 0
Регистрация: 25.12.2018
Сообщений: 12
26.08.2019, 11:59  [ТС] 4
Andrey B, спасибо, способ хороший, в твоём коде только какой-то косяк на этапе подсчёта, когда разберусь с <sstream> и его методами можно будет доделать.
nalbe666, вообще ничего не понял в С-коде, и я начинающий, поэтому сложно оценить Не работает только приоритет операций в parse, почти готовое решение, может кому нужно будет, благодарю!
0
812 / 500 / 210
Регистрация: 19.01.2019
Сообщений: 1,196
26.08.2019, 12:01 5
Цитата Сообщение от cleanbrain Посмотреть сообщение
Не работает только приоритет операций в parse
Почему не работает?
0
1 / 1 / 0
Регистрация: 25.12.2018
Сообщений: 12
26.08.2019, 16:38  [ТС] 6
Пример "2~2#2" у меня дал ответ 2, по приоритету должно быть сначала #, и значит 0.
0
812 / 500 / 210
Регистрация: 19.01.2019
Сообщений: 1,196
26.08.2019, 16:44 7
На все примеры из main результат = 0. В том числе и "2~2#2". Вы просто скопировали и запустили, или что-то меняли?
0
1 / 1 / 0
Регистрация: 25.12.2018
Сообщений: 12
27.08.2019, 11:32  [ТС] 8
У меня VS19, вместо "sscanf" говорит ставить "sscanf_s".
За исключением этого вы правы, полное копирование даёт все нули в ответах, я пытался через файл ввод сделать, значит где-то там была ошибка.
0
3319 / 1899 / 366
Регистрация: 09.09.2017
Сообщений: 7,732
27.08.2019, 13:45 9
Цитата Сообщение от cleanbrain Посмотреть сообщение
У меня VS19, вместо "sscanf" говорит ставить "sscanf_s".
Не верьте ему. Пропишите в начале файла #define _CRT_SECURE_NO_WARNINGS и продолжайте пользоваться стандартными функциями. Требование sscanf_s и подобных - известный баг msvs.
0
1 / 1 / 0
Регистрация: 25.12.2018
Сообщений: 12
27.08.2019, 22:20  [ТС] 10
Всё подключил, функции вернул в ваш вариант. С вводом как у вас работает, а с файлами на 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
int main() {
    int n = 0;
    char tmp;
    char* A;
    ifstream in;
    ofstream out;
    in.open("input.txt");
    while (in >> tmp){
        n++;
    }
    in.clear();
    in.seekg(0);
    A = new char[n];
    for (int i = 0; i < n; i++) {           
        in >> A[i];
    }
    A[n] = '\0';
    in.close();
    
    out.open("output.txt");
    out << calc(A, A + sizeof(A) - 1);
    out.close();
 
    return 0;
}
0
221 / 148 / 79
Регистрация: 14.03.2016
Сообщений: 459
27.08.2019, 23:21 11
cleanbrain, ох, давным давно писал ОПН, потому код большой и, возможно, костыльный (я не помню), однако если загнать в него ваши операции, то работать все будет так, как вы и хотели.
К счастью, код практически полностью прокомментирован, так что, надеюсь, разобраться в нем будет не очень сложно.

ещё кое-что

Закомментировал обычные команды где надо, т.к. не знаю их приоритет в данном задаче. Также много кода, который не относиться к данной задаче: переменные и вещественные. Извиняюсь за это нагромождение.


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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
#include <iostream>
#include <conio.h>
#include <string>
#include <stack>
#include <queue>
#include <map>
#include <math.h>
 
using namespace std;
 
int end() { cout << "\nEND\n"; _getch(); return 0; }
 
inline int prior(char& in)//возвращает приоритет операции
{
    /*if(in == '+' || in == '-')//если + или -,
        return 1;//то приоритет 1
    else if(in == '*' || in == '/')//если * или /,
        return 2;//то 2
    else if(in == '^')
        return 3;*/
    if(in == '~')
        return 1;
    else if(in == '#')
        return 2;
    else//если это вообще не операция, то возвращает 0
        return 0;
}
 
inline bool is_digit(char in)//говорит о том, число это или нет
{
    return (in >= '0' && in <= '9');
}
 
inline bool is_var(char in)//переменная ли
{
    return ((in >= 'a' && in <= 'z') ||
            (in >= 'A' && in <= 'Z'));
}
 
bool is_oper(char in)
{
    return (in == '+' || in == '-' ||
            in == '*' || in == '/' ||
            in == '^' || in == '#' || in == '~');
}
 
string stkTstr(stack<char> in)
{
    string ret;
    while(in.empty() == false)
    {
        //ret.insert(ret.begin(), in.top());
        ret += in.top();
        in.pop();
    }
    return ret;
}
 
string queTstr(queue<char> in)
{
    string ret;
    while(in.empty() == false)
    {
        ret.insert(ret.end(), in.front());
        in.pop();
    }
    return ret;
}
 
queue<char> to_revpol(const string& in)
{
    stack<char> stk;//создаем стак для хранения временных операция
    queue<char> gen;//создаем очередь, куда все будем пихать
    bool clbr = false;
    //for(auto i : in)//идем по строке
    char i; 
    string debug1, debug2;
    char last_op = '0';
    for(int j = 0; j < in.size(); j++)
    {
        i = in[j];
        if(i == '.' || i == ',')//если это просто точка, т.е. пользователь ввел число по типу 0.2,
            gen.push(i);//то тупо пихаем её внутрь
        else if(is_digit(i))//если сейчас число
        {
            if(( gen.empty() != true &&//если с gen что-то есть
                is_var(gen.back()) == true ) || clbr == true)//и это переменная или поднят флаг закрытой скобки, то...
            {
                stk.push('^'); gen.push(';'); clbr = false;
            }//это нужно, чтобы не писать знак степени после переменных и скобко, например, x2 == x^2 или (1+2)2 == (1+2)^2
            gen.push(i);
        }
        else if(is_var(i))//если сейчас переменная
        {
            if(gen.empty() != true &&//если с gen что-то есть
               is_digit(gen.back()) == true)//а сейчас у нас идет переменная, то...
            {
                stk.push('*'); gen.push(';');
            }//эта хрень нужна чтобы не ставить знак умножения перед переменной при вводе 5x == 5*x, например
            gen.push(i);
        }
        else if(is_oper(i))//если же это операция
        {//можно так же проверять по приоритетности, однако это ухудшит читаемость кода
            if(stk.empty() != true)//если в стэке что-то есть, то нужно посмотреть
            {
                if(prior(i) == prior(stk.top()))//если предыдущая и текущая операция имеют одинаковый приоритет,
                {
                    gen.push(stk.top());//то можно выгрузить предыдущую операцию
                    stk.top() = i;//и заменить её
                }
                else if(prior(i) < prior(stk.top()))//иначе, если приоритет текущей операции меньше,то
                {
                    while(stk.empty() != true && stk.top() != '(')//следует выгрузить все до открывающейся скобки, либо пока стек не опустеет
                    {//зачем? А переведите на ОПН такое: a * b + c. Тут роль скобочки играет главное тело.
                        gen.push(stk.top());
                        stk.pop();
                    }
                    stk.push(i);
                }
            }
            if(stk.empty() == true || prior(i) > prior(stk.top()))//если же стек пуст или проиритет последний операции меньше текущей, то...
            {
                if(gen.empty() != true &&
                   is_digit(gen.back()) || is_var(gen.back()))//если последнее, что было в gen - переменная или цифра, 
                    gen.push(';');//то следует поставить ограничивающий знак
                else if(( ( stk.empty() != true && stk.top() == '(' ) || gen.empty() == true ) && i == '-')//иначе,
                    gen.push('_');//если стек не пуст и последнее, что в него запили была открывающая скобка, либо у нас вообще пока ничего нет, а i == -, то я вставляю знак _
                //зачем? Ну, для того чтобы все не ломалось при таком вводе: -5 + 3 или 4 * (-2 + 1)
                if(gen.back() != '_')//если последнее в gen не _, которые мы могли только что записать => это какая-то операция
                    stk.push(i);
            }
        }
        else if(i == '(')//если же у нас не цифра, не переменная и не операция, а откр. скобка, то...
        {
            if(gen.empty() != true &&
                ( is_digit(gen.back()) || is_var(gen.back()) ))//если последнее что было в gen - переменная или цифра, 
            {
                gen.push(';');//ставим ограничивающий знак, а в стек записываем *
                stk.push('*');//Опять же, зачем? А затем, чтобы не ставить его самим при записи типа: 23(13 + 1), например
            }
            stk.push(i);//запихиваем ( в стэк
        }
        else if(i == ')')//если же у нас закрылась скобка, следует выгрущить все операции из stk в gen
        {
            clbr = true;
            while(stk.empty() != true && stk.top() != '(')//пока стек не пустой (если он опустел значит пользователь ввел неправильное выражение) и до, конечно, открывающийся скобки 
            {
                gen.push(stk.top());
                stk.pop();
            }
            if(stk.empty() != true)
                stk.pop();
            else
                throw "WRONG INPUT! Missing (";//кидаем исключение, если пользователь был не очень внимателен
        }
        debug1 = stkTstr(stk);
        debug2 = queTstr(gen);
        cout << "operation: " << i << endl
             << "last op.: " << last_op << endl
             << "stack: " << debug1 << endl
             << "generate: " << debug2 << endl << endl;
 
        if(i != '(' || i != ')') last_op = i;
    }
 
    while(stk.empty() != true)//по окончанию работы со строкой в стеке может что-то остаться, потому
    {//выносим все что осталось.
        gen.push(stk.top());
        stk.pop();
    }
    return gen;//и возвращаем результат
}
 
double calc(queue<char> in)
{
    stack<double> res;//временное хранилище значений
    map<string, double> mem;//чтобы дважды не запрашивать одну и ту же переменную
    string var_buf;//буфер строки при для переменных
    bool minus = false, op = false;//флаги на минус, либо на оперцию
    size_t fl = 0;//переменная для правильного ввода значений с плавающей точкой
    double temp;//и просто временная переменная
 
    res.push(0.0);//добавляем одно значение
    while(in.empty() != true)//пока очередь не опустеет
    {
        if(in.front() == '_')//если встретился знак _, значит был ввод типа: -3 + 2 или 5 * (-4 + 3) и т.д.
        {   
            minus = true;//поднимаем флаг минуса 
            in.pop();//убираем эл.
        }
        else if(is_digit(in.front()) == true)//если получили цифру
        {
            if(op == true) { res.push(0.0); op = false; }//если была какая-то операция и сейчас нам нужно записать новое значение, то добавляем память и опускаем флаг
            while(in.empty() != true && is_digit(in.front()) == true)//пока в очереди что-то есть и пока это цифры
            {
                if((in.front() == '0' && res.top() == 0.0) == false)//чтобы не умножать 0 на 10 и не прибавлять (48 - 48)
                {
                    if(fl == 0)//если не встречалось ., т.е. пока у нас обычное, целое число
                    {
                        res.top() = res.top() * 10 + in.front() - 48;
                    }
                    else//иначе
                    {
                        temp = in.front() - 48;//переводим символьное число в обычное
                        for(size_t i = 0; i < fl; i++)//и по счетчику разряда делим на 10
                            temp /= 10;
                        res.top() += temp;//и просто добавляем к текущему
                        fl++;//увеличиваем разряд
                    }
                }
                in.pop();//убираем эл.
                if(in.empty() != true && in.front() == '.')//если встретилась точка и очередь не пуста, то
                {
                    fl = 1;//счетчик разряда ставим в 1
                    in.pop();//и удаляем .
                }
            }
            fl = 0;//после считывания числа, обнуляем счетчик разрядов
        }
        else if(is_var(in.front()) == true)//если же нам встретилась переменная
        {
            if(op == true) { res.push(0.0); op = false; }//если до этого была операция, а теперь нам нужно ввести новое значение, то выделяем память
            var_buf.clear();//очищаем буфер
            do
            {//вносим название переменной в буфер. А в цикле за тем, чтобы можно было писать переменные не в одну букву
                var_buf.push_back(in.front());
                in.pop();
            }while(in.empty() != true && is_var(in.front()) == true);
                
            if(mem.find(var_buf) != mem.end())//проверяем, была ли такая переменная
            {
                res.top() = mem[var_buf];//если да, то присваиваем топу то запомненное значение
            }
            else//если же мы не нашли, то просим ввести новое значение
            {
                cout << "Please enter the variable \'" << var_buf << "\': ";//просим пользователя её ввести
                cin >> res.top();//вводим значение переменной с клавиатуры
                mem[var_buf] = res.top();//запоминаем переменную и её значение
            }
        }
        else if(in.front() == ';' ||
                is_oper(in.front()) == true)//если же нам наконец попалась операция
        {
            if(minus == true)//если флаг минуса поднят
            {
                minus = false;//опускаем флаг
                res.top() = -res.top();//умножаем текущее значение на -1
            }
            if(in.front() == ';')//если это знак разделитель, значит надо добавить памяти
            {
                res.push(0.0);//добавляем 
                in.pop();//убираем знак
            }
            else if(res.size() > 1)//иначе, если у нас уже что-то есть в стеке
            {
                temp = res.top();//пихаем в temp последнее значение
                res.pop();//убираем его из стека
                switch(in.front())//смотрим что это и делаем необходимые операции
                {
                    case '~':
                        res.top() = 2 * res.top() - temp;
                        break;
                    case '#':
                    case '+':
                        res.top() += temp;
                        break;
                    case '-':
                        res.top() -= temp;
                        break;
                    case '*':
                        res.top() *= temp;
                        break;
                    case '/':
                        res.top() /= temp;
                        break;
                    case '^':
                        res.top() = pow(res.top(), temp);
                }
                op = true;//ставим флаг операции
                in.pop();//убираем символ операции из очереди
            }
        }
    }
    if(res.size() > 1)//если вдруг в стеке осталось что-то кроме результата, выводим сообщение об ошибке и все, что осталось в стеке
    {
        cout << "something went wrong!";
        while(res.empty() != true)
        {
            cout << res.top() << ' ';
            res.pop();
        }
        return 0.0;
    }
    return res.top();//если же все хорошо, возвращаем результат
}
 
template <class T>
ostream& operator<<(ostream& out, queue<T> cs)
{
    while(cs.empty() != true)
    {
        out << cs.front();
        cs.pop();
    }
    return out;
}
 
int main()
{
    string in;
    queue<char> gen;
    cout << "Enter an expression:\n";
    //in = "2*(3-2+1)/0.2"; cout << in << endl;
    //in = "11(4*3+5)"; cout << in << endl;
    //in = "1/-1";
    getline(cin, in);
 
    gen = to_revpol(in);
    cout << "Result of the function to_revpol: " << gen << endl;
    cout << "Final result: " << calc(gen);
    return end();
}
Подумал, вдруг пригодится. Вот...
0
812 / 500 / 210
Регистрация: 19.01.2019
Сообщений: 1,196
28.08.2019, 03:34 12
Лучший ответ Сообщение было отмечено cleanbrain как решение

Решение

C++

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
#include <iostream>
#include <fstream>
#include <string>
 
size_t parse(const char* begin, const char* end, int* dest) {
    int a, b;
    const char* it;
    sscanf(begin, "%d", &a);
    for (it = begin; it != end; ++it) {
        if (*it == '~') {
            *dest++ = a;
            return parse(it + 1, end, dest) + 1;
        }
        if (*it == '#') {
            sscanf(it + 1, "%d", &b);
            a += b;
        }
    }
    *dest = a;
    return 1;
}
 
int calc(const char* begin, const char* end) {
    static int buff[BUFSIZ];
    size_t size = parse(begin, end, buff);
    int i, res = buff[0];
    for (i = 1; i < size; ++i) {
        res = res * 2 - buff[i];
    }
    return res;
}
 
int main()
{
    std::ifstream is("input.txt");
    if (!is.is_open()) {
        return 1;
    }
    std::ofstream os("output.txt");
    if (!os.is_open()) {
        return 1;
    }
 
    std::string buff;
    while (std::getline(is, buff)) {
        if (buff.empty()) {
            continue;
        }
        os << calc(buff.c_str(), buff.c_str() + buff.size()) << '\n';
    }
 
    is.close();
    os.close();
    return 0;
}
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.08.2019, 03:34

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Вычисление выражений с операциями отношения и логическими операциями
Лабораторная Работа № 5 Тема: Вычисление выражений с операциями отношения и логическими...

Массив с новыми элементами
Добрый вечер. Не получается написать программу которая коректно вычисляет элементы массива.Выводит...

Клонирование объекта с новыми параметрами
Доброго времени суток. Клонирую объект с новыми параметрами. Как это правильно записать? // В...

Не запускается с новыми планками ОЗУ
Здравствуйте дорогие Форумчане! У меня проблема с новыми планками оперативной памяти. Итак к...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.