请教给为前辈,编一个计算器(手工输入数字,并非按键),如何实现?(100分)

  • 主题发起人 主题发起人 Awei_Ying
  • 开始时间 开始时间
A

Awei_Ying

Unregistered / Unconfirmed
GUEST, unregistred user!
就是在文本框内输入算式,如 1+(2*5)/2 ,然后按结果按键,就得出结果,请问程序如何实现?
 
需要用到数据结构中讲到的堆栈的用法;
以下是本人写的计算逻辑表达式的值的代码。你可以参考一下:
{*******************************************************************************
程序说明:
一、本程序用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):分别完成入栈、出栈、取栈顶元素的
操作。
四、运算符的优先级:
! & | > = ( ) #
! > > > > > < > >
& < > > > > < > >
| < < > > > < > >
> < < < > > < > >
= < < < < > < > >
( < < < < < < = 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
'&':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:='!&|>=()#';

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;
'!','&','|','>','=','(',')':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.
 
一般的数据结构教程都有 队列 栈 和算术表达式的例子。
知道如何计算表达式,覆盖一下 wm_char 消息不就可以了。
 
找组件吧,肯定有,何必自己编。
 
后退
顶部