Задача №8 Урок №22
Primary tabs
"Калькулятор":
Напишите функцию, которая получает на вход произвольную строку вида:5*(3+4)-7*9+3*(2+(2-7))(арифметическое выражение со скобками любого уровня вложенности и операциями умножения, вычитания и сложения)
и в качестве ответа возвращает результат этого выражения.
Рекомендация: сначала убедитесь, что число открывающих скобок, равно числу закрывающих.
Решение:
var
s: string;
i: integer;
function arithmetic(num1,num2: integer; oper1: string): integer;
begin
case oper1 of
'+': num1 := num1 + num2;
'-': num1 := num1 - num2;
'*': num1 := num1 * num2;
end;
result := num1;
end;
function calc(var i: integer; s: string): integer;
var Code,num2,num3,num1,n1: integer; oper1,oper2, numstr1, numstr2, numstr3: string;
begin
n1:=0;
num1:= 0;
num2:= 0;
num3:= 0;
oper1:='';
while(i <= length(s)) do
begin
if n1<> 0 then
begin
if (s[i]<>'*') then
begin
num1:= arithmetic(n1,num1,oper1);
n1:=0;
oper1:='';
end
else
begin
num2:= num1;
num1:= n1;
n1:= 0;
end;
end;
if (s[i]>= '0') and (s[i] <= '9') then
begin
if (num1 = 0) then
begin
numstr1:= s[i];
val(numstr1,num1,Code);
if ((i=length(s)) and (n1 <> 0)) then
n1:= arithmetic(n1,num1,oper1);
end
else
begin
numstr2:= s[i];
val(numstr2,num2,Code);
if (i = length(s))or(oper1 = '*')or(s[i+1]= ')') then
begin
num1:= arithmetic(num1,num2,oper1);
num2:= 0;
oper1:= '';
if (s[i+1]=')')then
begin
if (i+1<>length(s)) then
inc(i);
break;
end;
end;
end;
end
else if(s[i] = '(') then
begin
if i<>1 then
n1:= num1;
inc(i);
num1:= calc(i,s);
end
else if(s[i] = ')') then
begin
if i = length(s) then
dec(i);
if num2<>0 then
num1:= arithmetic(num1,num2,oper1);
num2:= 0;
oper1:= '';
break;
end
else if (oper1 = '') then
oper1:= s[i]
else
begin
oper2:= s[i];
if (oper2 <> '*') then
begin
num1:= arithmetic(num1,num2,oper1);
numstr2:='';
oper1:= oper2;
oper2:= '';
num2:=0;
end
else
begin
if(s[i+1] <> '(') then
begin
inc(i);
numstr3:= s[i];
val(numstr3,num3,Code);
num2:= arithmetic(num2,num3,oper2);
num3:= 0;
oper2:= '';
num1:= arithmetic(num1,num2,oper1);
num2:= 0;
oper1:= '';
break;
end
else
begin
inc(i,2);
num3:= calc(i,s);
num2:= arithmetic(num2,num3,oper2);
num3:= 0;
oper2:= '';
if (i = length(s)) then
begin
num1:= arithmetic(num1,num2,oper1);
num2:= 0;
oper1:= '';
end;
end;
end;
end;
inc(i);
end;
if n1 = 0 then
result:= num1
else
result:= n1;
end;
begin
i:= 1;
s:= '5*(3+4)-7*9';
write(s);
write(' = ',calc(i,s));
readln();
end.
- Log in to post comments
- 1264 reads
vedro-compota
Fri, 07/05/2024 - 21:04
Permalink
По-идее алгоритмически
По-идее алгоритмически рекурсиный вызов достаточно делать когда встречаешь открывающую скобку как в первом случае, зачем такие вызовы по всех остальных случаях?
if(s[i] = '(') then begin if i<>1 then n1:= num1; inc(i); num1:= calc(i,s);_____________
матфак вгу и остальная классика =)
Pikachu
Mon, 07/08/2024 - 15:17
Permalink
Исправление
var s:string; i:integer; function calc(var i:integer;s:string):integer; var str:string; a,midnes:integer; minus,mult:boolean; begin minus := false; mult := false; result := 0; repeat i+=1; if(s[i]>='0') and (s[i]<='9') then str :=str+s[i] else begin if (s[i] = '(' ) then begin a :=calc(i,s); i +=1; end else val(str,a); if (minus) then begin a := a*(-1); minus := false; end; if (mult) then begin a := a * midnes; mult := false; end; if (s[i] = '*') then begin mult := true; midnes := a; end else result:= result+a; if s[i] = '-' then minus:= true; str:=''; end; until (s[i] = ')') or (i> length(s)); end; begin i:=0; s := '5*(3+(2*2-(2+2)))+7*9+3*(2+(2-7))+5'; writeln(s,' = ', calc(i, s)); readln(); end.