又是万恶的表达式解析.
用了黑科技:
首先用栈把括号给去掉,把区间给提取出来单独存然后用’$’ 代替
处理的时候就可以根据这是第几个’$’来处理,
其他数也是等价的
程序打了一个小时,不过我自己认为打的还是挺优美的.
DEMO
type
str_=string;
sec=record
l,r:double;
end;
var
ex:str_;
i,j,k:longint;
tmp:sec;
no0:boolean;
function max(a,b:double):double;
begin
if(a>b) then exit(a) else exit(b);
end;
function min(a,b:double):double;
begin
if(a>b) then exit(b) else exit(a);
end;
function copy0(ex:str_; be,ed:longint):str_;
begin
exit(copy(ex,be,ed-be+1));
end;
function pos0(ex:str_;be:longint;target:char):longint;
var i:longint;
begin
for i:=be to length(ex) do
if ex[i]=target then exit(i);
exit(0);
end;
function lastchar(str:str_; loc:longint):char;
var j:longint;
begin
for j:=loc-1 downto 1 do if (str[j]<>'#') then exit(str[j]);
end;
//格式: 数1,数2
function toSec(ex:str_):sec;
var i:longint;
rs:sec;
begin
for i:=1 to length(ex) do
if (ex[i]=',') then
begin
val(copy(ex,1,i-1),rs.l);
val(copy(ex,i+1,length(ex)),rs.r);
exit(rs);
end;
end;
function toString(x:sec):str_;
var s1,s2:str_;
begin
str(x.l,s1);
str(x.r,s2);
exit('['+s1+','+s2+']');
end;
procedure not0(var x:sec);
var
l,r:double;
begin
l:=min(-x.l,-x.r);
r:=max(-x.l,-x.r);
x.l:=l;
x.r:=r;
end;
function mul(a,b:sec):sec;
var
rs:sec;
begin
rs.l:=min(a.l*b.l,min(a.l*b.r,min(a.r*b.l,a.r*b.r)));
rs.r:=max(a.l*b.l,max(a.l*b.r,max(a.r*b.l,a.r*b.r)));
exit(rs);
end;
function divi(a,b:sec):sec;
var
rs:sec;
begin
if (b.l<=0)and(b.r>=0) then
begin
no0:=true;
exit(a);
end;
rs.l:=min(a.l/b.l,min(a.l/b.r,min(a.r/b.l,a.r/b.r)));
rs.r:=max(a.l/b.l,max(a.l/b.r,max(a.r/b.l,a.r/b.r)));
exit(rs);
end;
function add(a,b:sec):sec;
var
rs:sec;
begin
rs.l:=min(a.l+b.l,min(a.l+b.r,min(a.r+b.l,a.r+b.r)));
rs.r:=max(a.l+b.l,max(a.l+b.r,max(a.r+b.l,a.r+b.r)));
exit(rs);
end;
function minus(a,b:sec):sec;
var
rs:sec;
begin
rs.l:=min(a.l-b.l,min(a.l-b.r,min(a.r-b.l,a.r-b.r)));
rs.r:=max(a.l-b.l,max(a.l-b.r,max(a.r-b.l,a.r-b.r)));
exit(rs);
end;
function decode(ex:str_):sec;
var
st:array[0..100] of sec;
//stack:array[0..100] of char;
bloc,th,stot,top:longint;
isnotsec,last,k,j,i:longint;
loc:array[0..100] of longint;
pre,suf,stack,tmpp:str_;
tmp,rs,part:sec;
begin
rs.l:=0;
rs.r:=0;
if (no0) then exit(rs);
stack:='000000000000000000000000000000000000000000000';
//fillchar(stack,sizeof(stack),0);
fillchar(st,sizeof(st),0);
top:=0; stot:=0;
i:=1;
//解析括号与区间
while (i<=length(ex)) do
begin
if (ex[i]=')') then
begin
tmpp:='';
for j:=top downto 1 do
begin
dec(top);
if (stack[j]='(') then
begin
bloc:=loc[j];
break;
end;
if (stack[j]='$') then dec(stot);
end;
tmp:=decode(copy0(ex,bloc+1,i-1));
pre:=copy0(ex,1,bloc-1)+toString(tmp);
suf:=copy0(ex,i+1,length(ex));
i:=length(pre);
ex:=pre+suf;
inc(top);
stack[top]:='$';
inc(stot);
st[stot]:=tmp;
end else
if (ex[i]='[') then
begin
k:=pos0(ex,i,']');
inc(stot);
st[stot]:=toSec(copy0(ex,i+1,k-1));
inc(top);
stack[top]:='$';
loc[top]:=i;
i:=k;
end else
begin
inc(top);
stack[top]:=ex[i];
loc[top]:=i;
end;
inc(i);
end;
//取反
th:=0;
for i:=1 to top do
begin
if (stack[i]='$') then inc(th);
if (stack[i]='-') then
begin
if(stack[i+1]='$')and(stack[i-1]<>'$') then
begin
not0(st[th+1]);
stack[i]:='#';
end;
end;
end;
//乘除 加减
part.l:=-maxlongint;
part.r:=0;
th:=0;
last:=1;
for i:=1 to top do
begin
if (stack[i]='#') then continue;
if (stack[i]='$') then
begin
stack[i]:='#';
inc(th);
if (part.l=-maxlongint) then part:=st[th] else
begin
if (lastchar(stack,i)='*') then
part:=mul(part,st[th]);
if (lastchar(stack,i)='/') then
part:=divi(part,st[th]);
stack[i-1]:='#';
end;
end;
if (stack[i]='+')or(stack[i]='-') then
begin
if (last=1) then rs:=add(rs,part) else rs:=minus(rs,part);
if (stack[i]='+') then last:=1 else last:=-1;
part.l:=-maxlongint;
part.r:=0;
end;
end;
if (last=1)and(part.l<>-maxlongint) then rs:=add(rs,part) else rs:=minus(rs,part);
exit(rs);
end;
begin
assign(input,'2563.in'); reset(input);
while (not eof) do
begin
no0:=false;
readln(ex);
tmp:=decode(ex);
if (no0=false) then writeln('[',tmp.l:0:3,',',tmp.r:0:3,']')
else
writeln('Division by zero');
end;
end.