procedure ProcA(vcExpress:string);
var
AStackSrc,AStackDst:TStack;
i,iCount:integer;
AChar:Char;
pAChar:^Char;
pAItem:pChar;
AString,AStringRet:String;
pAString:^String;
begin
Try
AStackSrc:=TStack.Create;
AStackDst:=TStack.Create;
//================================
for iCount:=0 to Length(vcExpress) do
begin
pAChar:=@vcExpress[iCount];
AStackSrc.Push(pAChar);
end;
//================================
iCount:=AStackSrc.Count;
for i:=0 to iCount-1 do
begin
pAChar:=AStackSrc.Pop;
AChar:=pAChar^;
AStackDst.Push(pAChar);
if AChar=LBracket then
Begin
// new(pAString);
Repeat
// new(pAItem);
pAItem:=AStackDst.Pop;
AString:=AString+pAItem^;
Until (pAItem^=RBracket);
AStringRet:=AString;
// pAString:=AllocMem(Length(AStringRet));
// strCopy(pAString,pChar(AStringRet));
pAString:=@AStringRet;
AStackDst.Push(pAString);
AString:='';
memo1.Lines.Add(pAString);
End;
end;
Finally
AStackSrc.Free;
AStackDst.Free;
End;
End;
一个简单的解析表达式的过程
用表达式 vcExpress:='(((A+B)/(C+D+E)>15)and((D+E/(F+B))<16))'测试的结果:
(F+B)
(D+E/()
(<<16)
(C+D+E)
(A+B)
(??15)
(豠nd?
如果正确的话应该是如下的结果:
(F+B)
(D+E/(F+B))
((D+E/(F+B))<16)
(C+D+E)
(A+B)
((A+B)/(C+D+E)>15)
(((D+E/(F+B))<16)and((A+B)/(C+D+E)>15))
我估计问题出在
pAItem:=AStackDst.Pop;
AString:=AString+pAItem^;
而在AString入栈之后,再pop的时候,取得的不是当初入栈的字符串了;
var
AStackSrc,AStackDst:TStack;
i,iCount:integer;
AChar:Char;
pAChar:^Char;
pAItem:pChar;
AString,AStringRet:String;
pAString:^String;
begin
Try
AStackSrc:=TStack.Create;
AStackDst:=TStack.Create;
//================================
for iCount:=0 to Length(vcExpress) do
begin
pAChar:=@vcExpress[iCount];
AStackSrc.Push(pAChar);
end;
//================================
iCount:=AStackSrc.Count;
for i:=0 to iCount-1 do
begin
pAChar:=AStackSrc.Pop;
AChar:=pAChar^;
AStackDst.Push(pAChar);
if AChar=LBracket then
Begin
// new(pAString);
Repeat
// new(pAItem);
pAItem:=AStackDst.Pop;
AString:=AString+pAItem^;
Until (pAItem^=RBracket);
AStringRet:=AString;
// pAString:=AllocMem(Length(AStringRet));
// strCopy(pAString,pChar(AStringRet));
pAString:=@AStringRet;
AStackDst.Push(pAString);
AString:='';
memo1.Lines.Add(pAString);
End;
end;
Finally
AStackSrc.Free;
AStackDst.Free;
End;
End;
一个简单的解析表达式的过程
用表达式 vcExpress:='(((A+B)/(C+D+E)>15)and((D+E/(F+B))<16))'测试的结果:
(F+B)
(D+E/()
(<<16)
(C+D+E)
(A+B)
(??15)
(豠nd?
如果正确的话应该是如下的结果:
(F+B)
(D+E/(F+B))
((D+E/(F+B))<16)
(C+D+E)
(A+B)
((A+B)/(C+D+E)>15)
(((D+E/(F+B))<16)and((A+B)/(C+D+E)>15))
我估计问题出在
pAItem:=AStackDst.Pop;
AString:=AString+pAItem^;
而在AString入栈之后,再pop的时候,取得的不是当初入栈的字符串了;
应该是
for iCount:=0 to Length(vcExpress)-1 do
LBracket='(';
RBracket=')';
我贴个算法给你吧,大学编译课有讲过这个算法,没好好上课吧?代码就不能贴了,因为实现了比这个复杂的功能,而且属于公司财产,有算法不会写代码就是你的不对了。1.把中缀表达式换成后缀表达式(逆波兰式)
从左到右扫描中缀表达式(就是输入字符串inExpr),重复下述两步操作,直到表达式尾。
(1)从inExpr中取出下个sToken(数字、运算符、小括号)
(2)case sToken of
'(':将sToken压入栈;
操作数:将操作数加入outExpr; 如9,
操作符:如栈空或sToken比栈顶元素优先级高,将sToken进栈;
否则,出栈并将出栈元素加入outExpr,然后再将sToken与新栈顶元素比较;
')':出栈并将出栈元素加入outExpr,直到碰到'(','('出栈不加入outExpr。
(3)当inExpr扫描完毕,连续出栈并将出栈元素加到outExpr,直至栈空。2.对后缀表达式进行计算
栈stk初始化,用于存放计算结果
从左到右扫描outExpr,重复下述两步操作,直到表达式尾。
(1)从outExpr中取出下个sToken(数字、运算符)
(2)case sToken of
操作数:将操作数转换为double并入栈。
操作符:出栈两个操作数,对其进行运算符计算,结果入栈。
(3)当outExpr扫描完毕,栈顶的值就是计算结果。
在此感谢chuchu(维他命C)大侠的指点,你说得算法固然不错,但是我这里用不着这么复杂;可能算法没有注释,你看起来会比较乱!
其实我的设计思想很简单,当然表达式要按照如下的规则写:
1)凡运算关系式一定要用括号"()"括起来;如((A+B)>10)
2)凡表达式一定要用括号“()”括起来;如((A+B))
3) 最终的关系式要用括号“()”括起来;如(((A+B)>10)and((A+B)<20))
算法描述就是:
1,先将表达式入栈AStackSrc;
2,从AStackSrc出栈,入栈AStackDst;
3,当出栈字符是“(”时候,将AStackDst入栈的字符出栈,并组成字符串,直到遇到“)”为止;
4,将3)组成的字符串,入栈AStackSrc;然后继续1),直到AStackSrc为空;
从我测试的结果看,估计算法是没有问题的,问题出在
步骤4,入栈的字符串,取出来的好像不对;估计是字符串指针运用的不当!