Урок 18. Задача 11.
Primary tabs
Задана последовательность символов, имеющая следующий вид: p1q1p2q2p3...qn–1pn , где pi — число, а qi — знак арифметического действия из набора {+, –, *}. Вычислите значение выражения, предполагая, что действия выполняются согласно правилам арифметики.
Входные данные: На вход программе подается строка указанного вида, состоящая не более чем из 9 чисел, разделенных символами арифметических операций.
Выходные данные: Выведите значение арифметического выражения.
Как решать: Посчитайте результат за одно прочтение строки, без использования массивов (в нашем курсе решение в таком стиле для этой задачки было впервые добавлено участником slavina036).
(условие задачи взято из книги Е. В. Андреевой)
Var i, result, num_mul, vl_I, vl_C :integer;
s, str, chr :string;
fl_mul, fl_minus :boolean;
begin
s := '2*2*1-4-4+4+2*4';
chr := ''; // знак
result := 0; // ответ
num_mul := 0; // число из предыдущей итерации
fl_mul := false; // флаг умножения
fl_minus := false; // флаг для получения отрицательного числа
str := ''; // строка с актуальным числом
for i := 1 to length(s) + 1 do
begin
if i = length(s) + 1 then
s[i] := '+';
val(s[i], vl_I, vl_C);
if vl_C = 0 then // ищет число
str := str + s[i]
else
begin
chr := s[i]; // находит знак
val(str, vl_I);
str := '';
if fl_mul then // умножает
begin
fl_mul := false;
vl_I := num_mul * vl_I;
end
else
if fl_minus then // делает число отрицательным
begin
fl_minus := false;
vl_I := vl_I * (-1);
end;
if chr = '*' then
begin
fl_mul := true;
num_mul := vl_I;
end
else
begin
if chr = '-' then
fl_minus := true;
result := result + vl_I;
end;
end;
end;
write(s, ' = ', result);
readln();
end.
- Log in to post comments
- 7984 reads
vedro-compota
Wed, 09/28/2022 - 19:31
Permalink
Переписать так, чтоб val(s[i]
Переписать так, чтоб val(s[i], vl_I, vl_C); вызовалось только когда действительно ожидается что там число, и когда уже сформировано, т.е. напр. если выражение:
-- для '444' операция val() должна быть вызвана 1 раз
_____________
матфак вгу и остальная классика =)
Dennis80
Sun, 10/09/2022 - 12:12
Permalink
Var i, result, num_mul, vl_I,
Var i, result, num_mul, vl_I, vl_C :integer; s, str, chr :string; fl_mul, fl_minus :boolean; begin s := '2*2*1-4-4+4+2*4'; chr := ''; // знак result := 0; // ответ num_mul := 0; // число из предыдущей итерации fl_mul := false; // флаг умножения fl_minus := false; // флаг для получения отрицательного числа str := ''; // строка с актуальным числом for i := 1 to length(s) + 1 do begin if i = length(s) + 1 then fl_minus := false; if (s[i] >= '0') and (s[i] <= '9') then // ищет число str := str + s[i] else begin chr := s[i]; // находит знак val(str, vl_I); str := ''; if fl_mul then // умножает begin fl_mul := false; vl_I := num_mul * vl_I; end else if fl_minus then // делает число отрицательным begin fl_minus := false; vl_I := vl_I * (-1); end; if chr = '*' then begin fl_mul := true; num_mul := vl_I; end else begin if chr = '-' then fl_minus := true; result := result + vl_I; end; end; end; write(s, ' = ', result); readln(); end.vedro-compota
Sun, 10/09/2022 - 14:05
Permalink
добавить
_____________
матфак вгу и остальная классика =)
Dennis80
Wed, 10/26/2022 - 18:06
Permalink
Var i, result, remember,
Var i, result, remember, number :integer; s, str, chr :string; function result_int(int_1, int_2 :integer; chr :string) :integer; begin if chr = '*' then result_int := int_1 * int_2 else if chr = '-' then result_int := int_1 - int_2 else result_int := int_1 + int_2; end; begin s := '-2*2*1*1+0+8-2-2+0-0'; chr := ''; // знак result := 0; // ответ remember := 0; // число из предыдущей итерации str := ''; // строка с актуальным числом for i := 1 to length(s) + 1 do begin if i > length(s) then s[i - 1] := s[i - 1]; if (s[i] >= '0') and (s[i] <= '9') then // ищет число str := str + s[i] else begin val(str, number); str := ''; result := result_int(remember, number, chr); writeln(result); chr := ''; if s[i] = '*' then begin remember := result; chr := '*'; end else begin if s[i] = '-' then chr := '-'; remember := result; end; end; end; write(s, ' = ', result); readln(); end.Var i, result, remember, number :integer; s, str, chr :string; function result_int(int_1, int_2 :integer; chr :string) :integer; begin if chr = '*' then result_int := int_1 * int_2 else if chr = '-' then result_int := int_1 - int_2 else result_int := int_1 + int_2; end; function calculator(s :string; i :integer) :integer; begin while i < length(s) do begin if (s[i] >= '0') and (s[i] <= '9') then // ищет число begin str := str + s[i]; i += 1; end else begin val(str, number); str := ''; result := result_int(remember, number, chr); chr := ''; if s[i] = '*' then begin remember := result; chr := '*'; i += 1; end else begin if s[i] = '-' then chr := '-'; i += 1; remember := result; end; end; end; calculator := result; end; begin s := '-2*2*1+0+8-2-2*1+0-0'; i := 1; chr := ''; // знак result := 0; // ответ remember := 0; // число из предыдущей итерации str := ''; // строка с актуальным числом result := calculator(s, i); write(s, ' = ', result); readln(); end.vedro-compota
Wed, 10/26/2022 - 19:20
Permalink
Функция должна принимать на
if s[i] = '*' then begin remember := result; chr := '*'; i += 1; end else begin if s[i] = '-' then chr := '-'; i += 1; remember := result; end;_____________
матфак вгу и остальная классика =)
Dennis80
Wed, 11/02/2022 - 18:44
Permalink
Var i, result, remember,
Var i, result, remember, number :integer; s, str, chr :string; function result_int(int_1, int_2 :integer; chr :string) :integer; begin if chr = '*' then result_int := int_1 * int_2 else if chr = '-' then result_int := int_1 - int_2 else result_int := int_1 + int_2; end; function calculator(s :string) :integer; begin chr := ''; // знак result := 0; // ответ remember := 0; // число из предыдущей итерации str := ''; // строка с актуальным числом while i < length(s) do begin if (s[i] >= '0') and (s[i] <= '9') then // ищет число str := str + s[i] else begin val(str, number); str := ''; result := result_int(remember, number, s[i]); end; i += 1; end; calculator := result; end; begin s := '1+2*3+1'; result := calculator(s); write(s, ' = ', result); readln(); end.vedro-compota
Wed, 11/02/2022 - 19:21
Permalink
0+ 1+2-2
- обрабатываем умножение
_____________
матфак вгу и остальная классика =)
Dennis80
Wed, 11/09/2022 - 18:35
Permalink
Var i, j, result, remember,
Var i, j, result, remember, number, multy :integer; s, str, chr :string; fl :boolean; function calculator(s :string) :integer; begin j := 1; i := 1; chr := '+'; // знак result := 0; // ответ remember := 0; // число из предыдущей итерации multy := 0; number := 0; fl := false; str := ''; // строка с актуальным числом while i < length(s) + 2 do begin if i > length(s) then begin s[i - j] := s[i - j]; j += 1; end; if (s[i] >= '0') and (s[i] <= '9') then // ищет число str := str + s[i] else begin val(str, number); str := ''; if fl then begin number := remember * number; fl := false; end; if s[i] = '*' then begin remember := number; fl := true; end else begin if chr = '-' then result := result - number else result := result + number; chr := s[i]; end; writeln(result, '_res ', chr, '_chr ', remember, '_rem ', number, '_num ', multy, '_mul ', i, '_i '); end; i += 1; end; calculator := result; end; begin s := '-1+3*3+1+1*1*1'; result := calculator(s); write(s, ' = ', result); readln(); end.vedro-compota
Wed, 11/09/2022 - 18:54
Permalink
нельзя уходить от
нельзя уходить от декомпозиции в пользу более длинного блока
_____________
матфак вгу и остальная классика =)
Dennis80
Wed, 11/16/2022 - 17:47
Permalink
Var i, j, result, remember,
Var i, j, result, remember, number, multy :integer; s, str, chr :string; fl :boolean; function result_int(int_1, int_2 :integer; chr :string) :integer; begin if chr = '*' then result_int := int_1 * int_2 else if chr = '-' then result_int := int_1 - int_2 else result_int := int_1 + int_2; end; function calculator(s :string) :integer; begin j := 1; i := 1; chr := '+'; // знак result := 0; // ответ remember := 0; // число из предыдущей итерации multy := 0; number := 0; fl := false; str := ''; // строка с актуальным числом while i < length(s) + 2 do begin if i > length(s) then begin s[i - j] := s[i - j]; j += 1; end; if (s[i] >= '0') and (s[i] <= '9') then // ищет число begin str := str + s[i]; writeln(result, '_res ', chr, '_chr ', remember, '_rem ', number, '_num ', multy, '_mul ', i, '_i '); end else begin val(str, number); str := ''; if fl then begin number := result_int(remember, number, chr); fl := false; multy := number; chr := s[i]; end; if s[i] = '*' then begin remember := number; fl := true; end else result := result_int(result, number, chr); chr := s[i]; end; i += 1; end; calculator := result; end; begin s := '-1+2*3*1+1'; result := calculator(s); write(s, ' = ', result); readln(); end.vedro-compota
Sun, 12/04/2022 - 14:46
Permalink
1) Вынести получение
1) Вынести получение очередного числа в процедуру
2) Завести единственную переменную для знака операции и проверять в цикле только ее
3)
-- исправить
4) Убрать лишние переменные и уточнить назначение имеющихся в комментариях
_____________
матфак вгу и остальная классика =)
Dennis80
Sun, 12/11/2022 - 13:17
Permalink
Var i, j, c, n, result,
Var i, j, c, n, result, remember, number, multy :integer; s, str, chr :string; fl :boolean; procedure get_value(s :string; var n, i :integer); var fl_number :boolean; begin fl_number := false; for j := 1 to length(s) do begin if (s[i] >= '0') and (s[i] <= '9') then // ищет число begin str := str + s[i]; fl_number := true end else if fl_number then begin val(str, n, c); break; end; i += 1; end; end; function result_int(int_1, int_2, int_3 :integer; chr :string) :integer; begin if chr = '*' then result_int := int_2 * int_3 else if chr = '-' then result_int := int_1 - int_2 else result_int := int_1 + int_2; end; function calculator(s :string) :integer; begin j := 1; i := 1; chr := '+'; // знак result := 0; // ответ remember := 0; // число из предыдущей итерации multy := 0; number := 0; fl := false; //str := ''; while i <= length(s) do begin get_value(s, n, i); result := result_int(result, n, multy, chr); //writeln(n, ' ', ' chr', chr, ' i', i, ' ', s[i], ' r', result); chr := s[i]; if chr = '*' then multy := n; end; calculator := result; end; begin s := '2*4*3'; result := calculator(s); write(s, ' = ', result); readln(); end.vedro-compota
Sun, 12/11/2022 - 15:12
Permalink
1)
1)
-- не усложняем, сигнатуру, если надо вынести умножение, то используем обертку, для тренировки решить отдельно задачу 3 урока 16 http://fkn.ktu10.com/?q=node/13330
2)
1.1) лучше перейти на while
1,2) конвертировать число после окончания цикла
_____________
матфак вгу и остальная классика =)
Dennis80
Thu, 12/15/2022 - 18:42
Permalink
Var i, c, n, result, multy:
Var i, c, n, result, multy: integer; s, str: string; symb: char; fl: boolean; procedure get_value(s :string; var n, i :integer); begin str := ''; // запись числа while i < length(s) do begin i += 1; // итерации if (s[i] >= '0') and (s[i] <= '9') then // ищет число str := str + s[i] else break // стоп цикла end; val(str, n, c); end; function result_int(int_1, n: integer; symb: char): integer; begin if symb = '*' then result := int_1 * n else result := int_1 + n; end; function calculator(s: string): integer; begin i := 0; symb := '+'; // знак result := 0; // ответ multy := 1; // число для умножения из памяти fl := false; // флаг для умножения while i < length(s) do begin get_value(s, n, i); // получить число if symb = '-' then // делает число отрицательым n := -n; if fl then begin n := result_int(multy, n, symb); fl := false; end; symb := s[i]; // текущий символ if symb = '*' then begin multy := n; fl := true; end else result := result_int(result, n, symb); end; calculator := result; end; begin s := '-1-3*3*2-1'; result := calculator(s); write(s, ' = ', result); readln(); end.vedro-compota
Sun, 12/18/2022 - 16:09
Permalink
записать алгоритм решения
1) записать алгоритм решения задачи текстом
Начать можно так:
2) изменить работу с счетчиками:
-- i должно стоять на первом элементе предполагаемого числа
3) Добавить процедуру для получения очередного знака операции
_____________
матфак вгу и остальная классика =)
Dennis80
Sun, 12/25/2022 - 08:16
Permalink
Алгоритм программы
Var i, c, n, result, multy: integer; s, str: string; symb: char; fl: boolean; procedure get_char(s :string; var i: integer; var symb: char); var j: integer; // индекс в массиве cA; cA: array [1..4] of char = ('-', '+', '*', '/'); begin while i <= length(s) do begin for j := 1 to 4 do if s[i] = cA[j] then begin symb := cA[j]; i += 1; Exit; end; end; end; procedure get_value(s :string; var n, i :integer); begin str := ''; // запись числа while i <= length(s) do begin if (s[i] >= '0') and (s[i] <= '9') then // ищет число begin str := str + s[i]; i += 1; end else break; // стоп цикла end; val(str, n, c); end; function result_int(int_1, n: integer; symb: char): integer; begin if symb = '*' then result := int_1 * n else result := int_1 + n; end; function calculator(s: string): integer; begin i := 1; result := 0; // ответ fl := false; // флаг для умножения while i <= length(s) do begin get_value(s, n, i); // получить число if symb = '-' then // если знак предыдущей итерации " - ", n := -n; // то делает число отрицательным if fl then begin n := result_int(multy, n, symb); fl := false; end; get_char(s, i, symb); // текущий символ if symb = '*' then begin multy := n; fl := true; end else result := result_int(result, n, symb); end; calculator := result; end; begin s := '1+11*3*2-77'; result := calculator(s); write(s, ' = ', result); readln(); end.vedro-compota
Sun, 12/25/2022 - 13:08
Permalink
засчитано
засчитано, можно переходить к рекурсивному варианту
_____________
матфак вгу и остальная классика =)