又是万恶的表达式解析.
用了黑科技: 首先用栈把括号给去掉,把区间给提取出来单独存然后用’$’ 代替
处理的时候就可以根据这是第几个’$’来处理, 其他数也是等价的
程序打了一个小时,不过我自己认为打的还是挺优美的.
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;
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;
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(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.
转载请注明原文地址: https://ju.6miu.com/read-1305886.html