由于noip居然可能考这种东西,于是很不情愿的来回忆这道字符串神题。
后缀表达式的运算裸做就行了,而转后缀的时候只要把运算符之间的优先级推出即可,if流,反正感觉比打表好看些。
这种东西直接贴 代码算了:
program lmd;
const
snum='0123456789';
var
st:array[0..1000]of char;
num:array[0..1000]of real;
top,i,len:longint;
x,y:real;
s,ss,t:string;
procedure inf;
begin
assign(input,'Expression.in');
assign(output,'Expression.out');
reset(input);rewrite(output);
end;
procedure ouf;
begin
close(input);close(output);
end;
procedure init;
begin
readln(s); s:=s+'@';
end;
procedure bug;
begin
write('wrong input');
ouf; halt;
end;
function use(x,y:char):longint;
begin
if (x='+') or (x='-') then
begin
if (y='*') or (y='/') or(y='(') then exit(0);
{if (x='+') or (x='-') or(x=')') or (x='@') then }exit(1);
end;
if (x='*') or (x='/') then
begin
if (y='(') then exit(0);
exit(1);
end;
if x='(' then
begin
if y=')' then exit(2);
if y='@' then bug;
exit(0);
end;
if x=')' then
begin
if x='(' then bug;
exit(1);
end;
if x='@' then
begin
if y='@' then exit(2);
exit(0);
end;
end;
procedure prepare;
begin
top:=1; st[1]:='@';
i:=1; len:=length(s);
while i<=len do
begin
if pos(s[i],snum)>0 then
begin
ss:=s[i];
while pos(s[i+1],snum)>0 do
begin
inc(i); ss:=ss+s[i];
end;
t:=t+ss+' ';
end
else
begin
while use(st[top],s[i])=1 do
begin
t:=t+st[top]; dec(top);
end;
if use(st[top],s[i])=2 then
begin
st[top]:=' ';dec(top);
end
else
begin
inc(top); st[top]:=s[i];
end;
end;
inc(i);
end;
writeln(t);
end;
procedure work;
begin
i:=1; len:=length(t); top:=0;
while i<=len do
begin
if pos(t[i],snum)>0 then
begin
x:=ord(t[i])-ord('0');
while pos(t[i+1],snum)>0 do
begin
inc(i); x:=x*10+ord(t[i])-ord('0');
end;
inc(top); num[top]:=x;
inc(i);
end
else
begin
x:=num[top-1]; y:=num[top]; dec(top);
case t[i] of
'+':num[top]:=x+y;
'-':num[top]:=x-y;
'*':num[top]:=x*y;
'/':num[top]:=x/y;
end;
end;
inc(i);
end;
write(num[top]:0:5);
end;
begin
inf;
init;
prepare;
work;
ouf;
end.