如何根据输入的运算表达式 计算出结果(200分)

  • 主题发起人 主题发起人 whzww
  • 开始时间 开始时间
W

whzww

Unregistered / Unconfirmed
GUEST, unregistred user!
比如 我在edit 中输入 1+2+3 那么 有什么快速方法能计算出结果??

帮忙啊
 
找找第三方控件吧,好象有这种控件的。
要不就自己写一个解释器吧。
查查DFW,我记的以前有类似的讨论。
 
给出你的邮箱,我把自己写的一个源码给你。
 
whzww@163.com
谢谢了 :)))
 
请给我一份,seagal2222@sohu.com
 
邮件已发出。
 
这样的控件没有见过,不过可以自己写算法,数据结构里面“堆栈和队列”一章里有一个例子,
讲了表达式的计算:
我这里有一个计算布尔表达式的值的例子,给你参考一下;
{*******************************************************************************
程序说明:
一、本程序用Turbo pascal 编写, 程序假定所输入的逻辑表达式无语法错误;
二、为实现运算符优先算法,程序使用了两个堆栈:一个是Optr,用以存放运算符;另一个
是Opnd,用以存放操作数或中间运算结果;程序的基本思路如下:
1、逐个字符扫描表达式,统计命题变元的个数OpndNum,确定真值表的行数,即表达式
求值的循环次数Time;
2、将循环变量转换为长度为OpndNum的二进制字符串,字符串的每一个字符分别作为参
与运算的操作数,同时扫描表达式字符串和二进制字符串(从后向前),建立需要
求值的逻辑表达式,存入表达式堆栈ExpStk,字符'#'作为表达式结束符存入栈底。
3、置操作数栈为空栈,表达式起始符'#'作为操作符的栈底元素。
4、依次读取表达式栈ExpStk中的每一个字符,若是操作数则进Opnd栈,若是运算符则和
Optr栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕(两个'#'
相遇)。
三、为增加主程序的易读性,程序设七个过程和函数,分别如下:
1、DecToBin(I, weishu):将整型数I转换为指定位数的二进制字符串,如:
DecToBin(7,4)='0111';
2、Precede(c1, c2)返回运算符c1、c2的优先级关系;
3、Operate(a,theta,b):根据theta的值完成合取、析取、蕴涵、条件运算;
Neg(a):完成否定运算;
4、Push(stack,w),Pop(stack),Gettop(stack):分别完成入栈、出栈、取栈顶元素的
操作。
四、运算符的优先级:
! &amp
| > = ( ) #
! > > > > > < > >
&amp
< > > > > < > >
| < < > > > < > >
> < < < > > < > >
= < < < < > < > >
( < < < < < < = X
) > > > > > X > >
# < < < < < < X =
*******************************************************************************}
Program Matrix(Infile, OutFile);
const Arrmax=50;
Type Stk=Record
elem:Array[1..Arrmax] of Char;
top:0..Arrmax
end
{字符堆栈}
Rank='0'..'1';{布尔变量取值范围}
var Infile:file of string
{字符串输入文件}
Outfile:text
{真值表输出文件}
Optr, Opnd, ExpStk:stk
{运算符, 操作数, 运算表达式栈}
OpStr, PreStr:string
{运算符,优先级字符串}
Prearray:array[1..8, 1..8]of char
{优先级数组}
Opset:Set of char
{运算符集合}
ExpStr, NumStr:string
{表达式,二进制数字符串}
OpndNum:integer
{操作数个数}
i,j:integer;
time, Row:integer
{循环次数,循环变量}
w, X, theta:char;
a,b:Rank;

function DecToBin(i:integer
weishu:integer)string;
{将整型数转换为指定位数的二进制字符串}
var temp1, temp2:string;
j:integer;
begin
j:=i;
temp1:='';
while j<>0 do
begin
Str(j mod 2, temp2);
insert(temp2, temp1, 1);
j:=j div 2;
end;
while length(temp1)<weishu do insert('0', temp1, 1);
DectoBin:=temp1;
end
{of DecToBin}

function Precede(c1, c2:char):char
{返回c1, c2的优先级}
var m,n:integer;
begin
m:=1;
n:=1;
while c1<>OpStr[m] do m:=m+1;
while c2<>OpStr[n] do n:=n+1;
Precede:=Prearray[m,n];
end
{of Precede}

procedure Push(var stack:stk
w:char)
{入栈操作}
begin
stack.top :=stack.top+1;
stack.elem[stack.top]:=w;
end
{of Push}

function Pop(var stack:stk):char
{出栈函数}
begin
Pop:=stack.elem[stack.top];
stack.top :=stack.top -1;
end
{of Pop}

function Gettop(stack:stk):char
{取栈顶元素}
begin
Gettop:=stack.elem[stack.top];
end
{of Gettop}

function Operate(a:Rank
theta:char
b:Rank):Rank;
{根据thate的值完成'与','或','条件','等价'运算}
var temp:Rank;
begin
case theta of
'&amp;':if ((a='1') and (b='1')) then temp:='1' else temp:='0';
'|':if ((a='0') and (b='0')) then temp:='0' else temp:='1';
'>':if ((a='1') and (b='0')) then temp:='0' else temp:='1';
'=':if a=b then temp:='1' else temp:='0';
end
{case}
Operate:=temp;
end
{of Operate}


function Neg(a:Rank):Rank
{完成'非'运算}
begin
if a='0' then Neg:='1' else Neg:='0';
end
{of Neg}

begin
Assign(Infile, 'input.dat');
Reset(Infile);
Assign(Outfile, 'Outfile.dat');
Rewrite(Outfile);
read(Infile, ExpStr)
{读逻辑表达式}
close;

PreStr:='>>>>><>><>>>><>><<>>><>><<<>><>><<<<><>><<<<<<=X>>>>>X>><<<<<<X=';
OpStr:='!&amp;|>=()#';

for i:=1 to 8 do for j:=1 to 8 do
Prearray[i,j]:=PreStr[8*(i-1)+j]
{建立优先级数组}
OpSet:=[];
for i:=1 to length(OpStr) do OpSet:=OpSet+[OpStr]
{建立运算符集合}
OpndNUm:=0;
for i:=1 to length(ExpStr) do
if UpCase(ExpStr)='P' then OpndNum:=OpndNum+1;
{计算操作数个数}
time:=Round(exp(OpndNum*Ln(2.0)))-1
{根据操作数个数确定循环次数}
for Row:=0 to time do {开始循环}
begin
NumStr:=DecToBin(Row,OpndNum);
for i:=1 to length(NumStr) do write(Outfile, NumStr:2);
ExpStk.top :=0;
Push(ExpStk, '#');
i:=length(NumStr);
for j:=length(ExpStr) downto 1 do
case UpCase(ExpStr[j]) of
'P':begin
Push(ExpStk, NumStr);
i:=i-1;
end;
'!','&amp;','|','>','=','(',')':Push(ExpStk, ExpStr[j]);
end
{建立运算表达式的堆栈}
Opnd.top :=0;
Optr.top :=0;
Push(Optr, '#');
w:=Pop(ExpStk);
while Not ((w='#') and (Gettop(Optr)='#')) do
if (w IN OpSet)
then case Precede(Gettop(Optr), w) of
'<':begin
Push(Optr, w);
w:=Pop(ExpStk);
end
{栈顶元素优先级低, 运算符入栈}
'=':begin
X:=Pop(Optr);
w:=PopExpStk);
end
{脱括弧并接收下一个字符}
'>':begin
theta:=Pop(Optr);
if theta='!' then
begin
a:=Pop(Opnd);
Push(Opnd, Neg(a));
end
else begin
b:=Pop(Opnd);
a:=Pop(Opnd);
Push(Opnd, Operate(a, theta, b));
end
{else}
end
{退出堆栈并将运算结果入栈}
end {case}
else begin
Push(Opnd, w);
w:=Pop(ExpStk);
end;
X:=Gettop(Opnd);
writeln(Outfile, X:5);
end
{循环结束}
close(Outfile);
end.
 
多人接受答案了。
 
后退
顶部