本表达式求值程序支持加减乘除、乘方开方、括号嵌套,精确度约为十几位小数,并支持小数和多位数录入计算。支持最长 4GB 的表达式。
版权所有 Ceeji,保留所有权利。转载请注明出处并保留本注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | //By Ceeji //Date: 2009-4-16 //Type: Stack //State: Accepted //For LL //简要说明:支持加减乘除、乘方开方、括号嵌套,精确度约为十几位小数,并支持小数和多位数录入计算。支持最长 4GB 的表达式。 //版权所有,保留所有权利。使用时必须保留注释。 Program biaodashi; Const p='+-*/^()#'; c:array[1..8,1..8]of integer= {+ - * / ^ ( ) #} {+} ((1, 1, 0, 0, 0, 0, 1, 1), {-} (1, 1, 0, 0, 0, 0, 1, 1), {*} (1, 1, 1, 1, 0, 0, 1, 1), {/} (1, 1, 1, 1, 0, 0, 1, 1), {^} (1, 1, 1, 1, 1, 0, 1, 1), {(} (0, 0, 0, 0, 0, 0, 2, 1), {)} (3, 3, 3, 3, 3, 3, 3, 3), {#} (0, 0, 0, 0, 0, 0, 0, 2) ); Var i,j,k:longint; a,jg:extended; s:ansistring; //计算两个数加减乘除或乘方,支持小数指数。 Function jisuan(shu1,shu2:extended; k:longint):extended; Var jg:extended; begin case k of 1: jg:=shu1+shu2; 2: jg:=shu1-shu2; 3: jg:=shu1*shu2; 4: jg:=shu1/shu2; 5: jg:=exp(shu2*ln(shu1)); end; jisuan:=jg; end; //把带有空格的表达式转换为标准表达式以便进行计算。本程序为辅助子程序。 Function guifan(st:ansistring):ansistring; var sn,ste:ansistring; i,j,max:integer; begin i:=0; sn:=st; max:=length(st); while i<max do begin i:=i+1; if sn[i]=' ' then begin for j:=i+1 to max do begin sn[j-1]:=sn[j]; end; max:=max-1; i:=i-1; continue; end; end; guifan:=copy(sn,1,max); end; //计算表达式子程序。主要的子程序。 Function jisuanbiaodashi(st:ansistring):extended; // st: 要计算的表达式。返回值为 extended,精确度比较高。 var i,j,k,ls,lf,t,len:longint; x:extended; b,bb:boolean; shu:array[1..100]of extended; fu :array[1..100]of longint; s :ansistring; begin fillchar(shu,sizeof(shu),0); fillchar(fu,sizeof(fu),0); s:='#'+st+'#'; ls:=0; lf:=0; i:=0; len:=length(s); repeat begin shu[ls+1]:=0; b:=false; bb:=false; i:=i+1; while (((s[i]>='0')and(s[i]<='9')))or(s[i]='.') do begin b:=true; if (s[i]<>'.')and(bb=false) then begin val(s[i],x); shu[ls+1]:=10*shu[ls+1]+x; i:=i+1; continue; end; if s[i]='.' then begin bb:=true; i:=i+1; t:=i-1; continue; end; if bb=true then begin val(s[i],x); shu[ls+1]:=shu[ls+1]+ x*1/exp((i-t)*ln(10)); i:=i+1; continue; end; end; if b=true then begin ls:=ls+1; i:=i-1; continue; end; k:=pos(s[i],p); if (k=0)or(k>8) then begin writeln('error'); exit; end; inc(lf); fu[lf]:=k; while (lf>1)and(c[fu[lf-1],fu[lf]]<>0)do begin if c[fu[lf-1],fu[lf]]=2 then begin dec(lf,2); continue; end; shu[ls-1]:=jisuan(shu[ls-1],shu[ls],fu[lf-1]); dec(ls); dec(lf); fu[lf]:=fu[lf+1]; end; end; until i>=len; jisuanbiaodashi:=shu[1]; end; begin readln(s); jg:=jisuanbiaodashi(guifan(s)); writeln(jg:0:3); //保留三位小数。可以修改这个数值以便获得更高的精度。 readln; end.{main} |
冀哥让我来留言
@chenzhe:膜拜