用 树 计算 表达式

可以没有用数这个数据结构,可以用子程序递归的栈来模拟数。


要注意的方面:

  1. 先要给运算符一个等级
    一般:
    +-:1
    */:2
    ^:3
    ~(负号):4
    ():5
    num:6

    负号要和减号要分开,在数字和)后面的是减号,在其他符号后面的是负号
  2. 扫描的时候要跳过括号
    比如1×(1+2)×3
    要跳过括号,否则将选择+
  3. 扫描字符串的时候,要倒着扫描(运算等级判断用<和>)。
    比如:  2/3×4
    顺着扫描的话,会最终指向2/3的/,则计算会变成2/(3×4),显然是错误的。
    倒着搜的话,最指向×,即计算为(2/3)×4;

下面是代码:

var
	expr:string;
function is_num(a:char):boolean;
begin
	if(a>='0')and(a<='9')then exit(true) else exit(false);
end;
function init(a:string):string;
var
	b:string;
	i:longint;
	t:boolean;
begin
	b:='';
	for i:=1 to length(a) do
		if a[i]<>' ' then b:=b+a[i];
	t:=true;
	for i:=1 to length(b) do begin
		if b[i]='-' then begin
			if t then b[i]:='~';
			t:=true;
		end else
		if is_num(b[i])or (b[i]=')') then t:=false else t:=true;
	end;
	exit(b);
end;
function pow(a,b:longint):longint;
var i:longint;
begin
        if a=0 then exit(0);
        if b=0 then exit(1);
        pow:=1;
        for i:=1 to b do pow:=pow*a;
end;
function work(a:string):longint;
var
	i,len,r,lev,p1,p2:longint;
        d:double;
	c:char;
begin
	len:=length(a);
	lev:=6;
	c:='1';
	r:=0;
	for i:=len downto 1 do begin
		if a[i]=')' then begin
			if (r=0)and(lev>5) then begin
					lev:=5;
					p2:=i;
					c:='$';
			end;
			inc(r);
		end;
		if a[i]='(' then begin
			dec(r);
			if (r=0)and(lev=5) then p1:=i;
		end;
		if r=0 then
		case a[i] of
			'+':if lev>1 then begin lev:=1;p1:=i;c:='+';end;
			'-':if lev>1 then begin lev:=1;p1:=i;c:='-';end;
			'*':if lev>2 then begin lev:=2;p1:=i;c:='*';end;
			'/':if lev>2 then begin lev:=2;p1:=i;c:='/';end;
			'^':if lev>3 then begin lev:=3;p1:=i;c:='^';end;
			'~':if lev>4 then begin lev:=4;p1:=i;c:='~';end;
		end;
	end;
	if c='+' then exit(work(copy(a,1,p1-1))+work(copy(a,p1+1,len-p1)));
	if c='-' then exit(work(copy(a,1,p1-1))-work(copy(a,p1+1,len-p1)));
	if c='*' then exit(work(copy(a,1,p1-1))*work(copy(a,p1+1,len-p1)));
	if c='/' then exit(trunc(work(copy(a,1,p1-1))/work(copy(a,p1+1,len-p1))));
	if c='^' then exit(pow(work(copy(a,1,p1-1)),work(copy(a,p1+1,len-p1))));
	if c='~' then exit(0-work(copy(a,2,len-1)));
	if c='$' then exit(work(copy(a,p1+1,p2-p1-1)));
	if c='1' then begin val(a,d);exit(trunc(d));end;
end;
begin
	readln(expr);
	expr:=init(expr);
	writeln(work(expr));
end.


这个是tyvj1043的代码,只能进行整数运算,如果要进行实数运算,则把longint改成double就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值