算符优先算法的问题 ( 积分: 100 )

  • 主题发起人 主题发起人 xxw553
  • 开始时间 开始时间
X

xxw553

Unregistered / Unconfirmed
GUEST, unregistred user!
写了个算符优先算法,计算如下公式情况时出错:(12+23+abs(34-422))/2,如果去掉abs函数(12+23+(34-422))/2正确,或者只有一个括号如:12+23+abs(34-422)/2也正确,源码如下:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type

PMyopstr=^myopstr;
myopstr=record
str:char;
prev:Pmyopstr;
end;
PMyopnd=^myopnd;
myopnd=record
nd:real;
prev:pmyopnd;
end;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Edit10: TEdit;
Edit11: TEdit;
Edit12: TEdit;
Edit13: TEdit;
Edit14: TEdit;
Edit15: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);

private

{ Private declarations }
public
op:array[0..7] of char;
optr,tmpoptr,headoptr,lastoptr:pmyopstr;
opnd,tmpopnd,headopnd,lastopnd:pmyopnd;
tmpstr:array[0..20]of string;
{ Public declarations }
end;


var
Form1: TForm1;

implementation

{$R *.dfm}
function inop(c:string;op:array of char):boolean;
var
i:integer;
begin
inop:=false;
for i:=0 to 6 do
if op=c then
begin
inop:=true;
end;
if c='abs' then inop:=true;
end;
procedure pushopnd(c:string);
begin
try
new(form1.opnd);
form1.opnd^.nd:=strtofloat(c);
form1.opnd^.prev:=nil;
if form1.headopnd=Nil then form1.headopnd:=form1.opnd
else form1.opnd^.Prev:=form1.lastopnd;
form1.lastopnd:=form1.opnd;
except
end;
end;
procedure pushoptr(c:char);
begin
new(form1.optr);
form1.optr^.str:=c;
form1.optr^.prev:=nil;
form1.optr^.prev:=form1.lastoptr;
form1.lastoptr:=form1.optr;
end;
function popoptr:string;
begin
popoptr:=form1.lastoptr^.str;
form1.optr:=form1.lastoptr;
form1.lastoptr:=form1.lastoptr^.prev;
dispose(form1.optr);
end;
function popopnd:real;
begin
popopnd:=form1.lastopnd^.nd;
form1.opnd:=form1.lastopnd;
form1.lastopnd:=form1.lastopnd^.prev;
dispose(form1.opnd)
end;
function gettopoptr:char;
begin
gettopoptr:=form1.lastoptr^.str;
end;
function operate(a:real;theta:string;b:real):Double ;
begin
if theta='+' then operate:=b+a
else if theta='*' then operate:=b*a
else if theta='-' then operate:=a-b
else if theta='/' then operate:=a/b
else if theta='a' then operate:=abs(a);
end;
function precede(optrtop:char;c:char):char;
begin
case optrtop of
'+':case c of
'+','-',')','#':precede:='>';
'*','/','(','a':precede:='<';
else showmessage('新读入的字符不是运算符!');
end;
'-':case c of
'+','-',')','#':precede:='>';
'*','/','(','a':precede:='<';
else showmessage('新读入的字符不是运算符!');
end;
'*':case c of
'+','-',')','#','*','/':precede:='>';
'(','a':precede:='<'
else showmessage('新读入的字符不是运算符!');
end;
'/':case c of
'+','-',')','#','*','/':precede:='>';
'(','a':precede:='<'
else showmessage('新读入的字符不是运算符!');
end;
'(':case c of
'+','-','(','*','/','a':precede:='<';
')':precede:='=';
else showmessage('新读入的字符不是运算符!');
end;
')':case c of
'+','-',')','#','*','/':precede:='>';
'(':showmessage('不允许出现)(的情况!');
else showmessage('新读入的字符不是运算符!');
end;
'a':case c of
'+','-','*','/',')':precede:='>';
'(':precede:='<';
else showmessage('新读入的字符不是运算符!');
end;
'#':case c of
'+','-','(','*','/':precede:='<';
'#':precede:='=';
')':showmessage('不允许出现#(的情况!');
else showmessage('新读入的字符不是运算符!');
end;
else showmessage('运算符栈的栈顶字符不是运算符!');
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
op[0]:='+';
op[1]:='-';
op[2]:='*';
op[3]:='/';
op[4]:='(';
op[5]:=')';
op[6]:='#';
op[7]:='a';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
popoptrchar:string;
popopndchara:real;
popopndcharb:real;
operatechar:real;
jieguo:string;
begin
while gettopoptr<>'#' do
begin
popoptrchar:=popoptr;
if popoptrchar<>'a' then
begin
popopndcharb:=popopnd;
popopndchara:=popopnd;
end
else
begin
popopndchara:=popopnd;
popopndcharb:=0;
end;
operatechar:=operate(popopndchara,popoptrchar,popopndcharb);
pushopnd(floattostr(operatechar));
end;
jieguo:=floattostr(popopnd);
showmessage('计算结果是:'+jieguo);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
getchar:char;
i:integer;
Popoptrchar:string;
popopndchara:real;
popopndcharb:real;
operatechar:real;
key:array[0..1] of char;
begin
headoptr:=nil;
lastoptr:=nil;
headopnd:=nil;
lastopnd:=nil;
new(optr);
optr^.str:='#';
optr^.prev:=nil;
headoptr:=optr;
lastoptr:=optr;
if edit1.Text<>'' then tmpstr[0]:=trim(edit1.Text)
else tmpstr[0]:='#';
if edit2.Text<>'' then tmpstr[1]:=trim(edit2.Text)
else tmpstr[1]:='#';
if edit3.Text<>'' then tmpstr[2]:=trim(edit3.Text)
else tmpstr[2]:='#';
if edit4.Text<>'' then tmpstr[3]:=trim(edit4.Text)
else tmpstr[3]:='#';
if edit5.Text<>'' then tmpstr[4]:=trim(edit5.Text)
else tmpstr[4]:='#';
if edit6.Text<>'' then tmpstr[5]:=trim(edit6.Text)
else tmpstr[5]:='#';
if edit7.Text<>'' then tmpstr[6]:=trim(edit7.Text)
else tmpstr[6]:='#';
if edit8.Text<>'' then tmpstr[7]:=trim(edit8.Text)
else tmpstr[7]:='#';
if edit9.Text<>'' then tmpstr[8]:=trim(edit9.Text)
else tmpstr[8]:='#';
if edit10.Text<>'' then tmpstr[9]:=trim(edit10.Text)
else tmpstr[9]:='#';
if edit11.Text<>'' then tmpstr[10]:=trim(edit11.Text)
else tmpstr[10]:='#';
if edit12.Text<>'' then tmpstr[11]:=trim(edit12.Text)
else tmpstr[11]:='#';
if edit13.Text<>'' then tmpstr[12]:=trim(edit13.Text)
else tmpstr[12]:='#';
if edit14.Text<>'' then tmpstr[13]:=trim(edit14.Text)
else tmpstr[13]:='#';
if edit15.Text<>'' then tmpstr[14]:=trim(edit15.Text)
else tmpstr[14]:='#';
i:=0;
while tmpstr<>'#' do
begin
strlcopy(key,pchar(tmpstr),1);
getchar:=key[0];
if (not inop(tmpstr,op)) then
pushopnd(tmpstr)
else
case precede(gettopoptr,getchar) of
'<':pushoptr(getchar);
'=':popoptrchar:=popoptr;
'>':begin
popoptrchar:=popoptr;
if popoptrchar<>'a' then
begin
popopndcharb:=popopnd;
popopndchara:=popopnd;
end
else
begin
popopndchara:=popopnd;
popopndcharb:=0;
end;
operatechar:=operate(popopndchara,popoptrchar,popopndcharb);
pushopnd(floattostr(operatechar));
if (getchar=')') then
popoptrchar:=popoptr;
if (getchar<>'#') and (getchar<>')') then pushoptr(getchar)
end;
else showmessage('不知道的错');
end;
i:=i+1;
end;
end;
end.
 
写了个算符优先算法,计算如下公式情况时出错:(12+23+abs(34-422))/2,如果去掉abs函数(12+23+(34-422))/2正确,或者只有一个括号如:12+23+abs(34-422)/2也正确,源码如下:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type

PMyopstr=^myopstr;
myopstr=record
str:char;
prev:Pmyopstr;
end;
PMyopnd=^myopnd;
myopnd=record
nd:real;
prev:pmyopnd;
end;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Edit10: TEdit;
Edit11: TEdit;
Edit12: TEdit;
Edit13: TEdit;
Edit14: TEdit;
Edit15: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);

private

{ Private declarations }
public
op:array[0..7] of char;
optr,tmpoptr,headoptr,lastoptr:pmyopstr;
opnd,tmpopnd,headopnd,lastopnd:pmyopnd;
tmpstr:array[0..20]of string;
{ Public declarations }
end;


var
Form1: TForm1;

implementation

{$R *.dfm}
function inop(c:string;op:array of char):boolean;
var
i:integer;
begin
inop:=false;
for i:=0 to 6 do
if op=c then
begin
inop:=true;
end;
if c='abs' then inop:=true;
end;
procedure pushopnd(c:string);
begin
try
new(form1.opnd);
form1.opnd^.nd:=strtofloat(c);
form1.opnd^.prev:=nil;
if form1.headopnd=Nil then form1.headopnd:=form1.opnd
else form1.opnd^.Prev:=form1.lastopnd;
form1.lastopnd:=form1.opnd;
except
end;
end;
procedure pushoptr(c:char);
begin
new(form1.optr);
form1.optr^.str:=c;
form1.optr^.prev:=nil;
form1.optr^.prev:=form1.lastoptr;
form1.lastoptr:=form1.optr;
end;
function popoptr:string;
begin
popoptr:=form1.lastoptr^.str;
form1.optr:=form1.lastoptr;
form1.lastoptr:=form1.lastoptr^.prev;
dispose(form1.optr);
end;
function popopnd:real;
begin
popopnd:=form1.lastopnd^.nd;
form1.opnd:=form1.lastopnd;
form1.lastopnd:=form1.lastopnd^.prev;
dispose(form1.opnd)
end;
function gettopoptr:char;
begin
gettopoptr:=form1.lastoptr^.str;
end;
function operate(a:real;theta:string;b:real):Double ;
begin
if theta='+' then operate:=b+a
else if theta='*' then operate:=b*a
else if theta='-' then operate:=a-b
else if theta='/' then operate:=a/b
else if theta='a' then operate:=abs(a);
end;
function precede(optrtop:char;c:char):char;
begin
case optrtop of
'+':case c of
'+','-',')','#':precede:='>';
'*','/','(','a':precede:='<';
else showmessage('新读入的字符不是运算符!');
end;
'-':case c of
'+','-',')','#':precede:='>';
'*','/','(','a':precede:='<';
else showmessage('新读入的字符不是运算符!');
end;
'*':case c of
'+','-',')','#','*','/':precede:='>';
'(','a':precede:='<'
else showmessage('新读入的字符不是运算符!');
end;
'/':case c of
'+','-',')','#','*','/':precede:='>';
'(','a':precede:='<'
else showmessage('新读入的字符不是运算符!');
end;
'(':case c of
'+','-','(','*','/','a':precede:='<';
')':precede:='=';
else showmessage('新读入的字符不是运算符!');
end;
')':case c of
'+','-',')','#','*','/':precede:='>';
'(':showmessage('不允许出现)(的情况!');
else showmessage('新读入的字符不是运算符!');
end;
'a':case c of
'+','-','*','/',')':precede:='>';
'(':precede:='<';
else showmessage('新读入的字符不是运算符!');
end;
'#':case c of
'+','-','(','*','/':precede:='<';
'#':precede:='=';
')':showmessage('不允许出现#(的情况!');
else showmessage('新读入的字符不是运算符!');
end;
else showmessage('运算符栈的栈顶字符不是运算符!');
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
op[0]:='+';
op[1]:='-';
op[2]:='*';
op[3]:='/';
op[4]:='(';
op[5]:=')';
op[6]:='#';
op[7]:='a';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
popoptrchar:string;
popopndchara:real;
popopndcharb:real;
operatechar:real;
jieguo:string;
begin
while gettopoptr<>'#' do
begin
popoptrchar:=popoptr;
if popoptrchar<>'a' then
begin
popopndcharb:=popopnd;
popopndchara:=popopnd;
end
else
begin
popopndchara:=popopnd;
popopndcharb:=0;
end;
operatechar:=operate(popopndchara,popoptrchar,popopndcharb);
pushopnd(floattostr(operatechar));
end;
jieguo:=floattostr(popopnd);
showmessage('计算结果是:'+jieguo);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
getchar:char;
i:integer;
Popoptrchar:string;
popopndchara:real;
popopndcharb:real;
operatechar:real;
key:array[0..1] of char;
begin
headoptr:=nil;
lastoptr:=nil;
headopnd:=nil;
lastopnd:=nil;
new(optr);
optr^.str:='#';
optr^.prev:=nil;
headoptr:=optr;
lastoptr:=optr;
if edit1.Text<>'' then tmpstr[0]:=trim(edit1.Text)
else tmpstr[0]:='#';
if edit2.Text<>'' then tmpstr[1]:=trim(edit2.Text)
else tmpstr[1]:='#';
if edit3.Text<>'' then tmpstr[2]:=trim(edit3.Text)
else tmpstr[2]:='#';
if edit4.Text<>'' then tmpstr[3]:=trim(edit4.Text)
else tmpstr[3]:='#';
if edit5.Text<>'' then tmpstr[4]:=trim(edit5.Text)
else tmpstr[4]:='#';
if edit6.Text<>'' then tmpstr[5]:=trim(edit6.Text)
else tmpstr[5]:='#';
if edit7.Text<>'' then tmpstr[6]:=trim(edit7.Text)
else tmpstr[6]:='#';
if edit8.Text<>'' then tmpstr[7]:=trim(edit8.Text)
else tmpstr[7]:='#';
if edit9.Text<>'' then tmpstr[8]:=trim(edit9.Text)
else tmpstr[8]:='#';
if edit10.Text<>'' then tmpstr[9]:=trim(edit10.Text)
else tmpstr[9]:='#';
if edit11.Text<>'' then tmpstr[10]:=trim(edit11.Text)
else tmpstr[10]:='#';
if edit12.Text<>'' then tmpstr[11]:=trim(edit12.Text)
else tmpstr[11]:='#';
if edit13.Text<>'' then tmpstr[12]:=trim(edit13.Text)
else tmpstr[12]:='#';
if edit14.Text<>'' then tmpstr[13]:=trim(edit14.Text)
else tmpstr[13]:='#';
if edit15.Text<>'' then tmpstr[14]:=trim(edit15.Text)
else tmpstr[14]:='#';
i:=0;
while tmpstr<>'#' do
begin
strlcopy(key,pchar(tmpstr),1);
getchar:=key[0];
if (not inop(tmpstr,op)) then
pushopnd(tmpstr)
else
case precede(gettopoptr,getchar) of
'<':pushoptr(getchar);
'=':popoptrchar:=popoptr;
'>':begin
popoptrchar:=popoptr;
if popoptrchar<>'a' then
begin
popopndcharb:=popopnd;
popopndchara:=popopnd;
end
else
begin
popopndchara:=popopnd;
popopndcharb:=0;
end;
operatechar:=operate(popopndchara,popoptrchar,popopndcharb);
pushopnd(floattostr(operatechar));
if (getchar=')') then
popoptrchar:=popoptr;
if (getchar<>'#') and (getchar<>')') then pushoptr(getchar)
end;
else showmessage('不知道的错');
end;
i:=i+1;
end;
end;
end.
 
看看我的程序: http://www.delphibbs.com/delphibbs/dispq.asp?lid=3253671
很容易的...
 
没人回答吗?顶起
 
看看我的程序: http://www.delphibbs.com/delphibbs/dispq.asp?lid=3253671
很容易的...
 
后退
顶部