那位做过公式解析方面的东西,能否赐教一二? 希望有经验的大虾来看看 (100分)

  • 主题发起人 主题发起人 dansl
  • 开始时间 开始时间
D

dansl

Unregistered / Unconfirmed
GUEST, unregistred user!
本人在搞一个公式解析东东,下了一个parser10的组件,可是觉得我把大部分工作做完了,只是用他计算了下,有经验的大虾能否探讨一下这个问题
 
parser10没用过,我曾做过公式解析,读读编译原理就行
 
hoho,公式解析我只会用JavaScript
 
to szgh: 那有编译原理的ebook?
to takashiki:可我不会java
 
用sql语句可以很简单搞定
select 2+(5+123)*56/5 as a
 
搜索以下,其实我们多数只是需要一个表达式解析,很简单.
 
它是一个字符一个字符的分析,有空格就跳过是数字就进行相应的运算,是字母就找函数,进行函数运算。
 
我本来就是用sql,但是效率太慢,才要改成公式解析,我的公式没有太复杂的函数,基本上就是+-×/()什么的,但是我的变量都是一些标记,不是单字母的,搞的我不知如何下手了
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1967738
 
还有人提点意见吗
 
写一个过程,然后用递归调用方法完全可以实现。
 
是不是表达式求解的意思啊
可以用个运算符栈和操作数栈来扫描表达式求解
最近在研究数据结构就来写了一个
偷了点懒,两个栈用了同一种结构指针

------------------------------------------------
下面是个结构定义和栈操作单元
unit stackunit;
interface
type
pointer=^node;
node=record
x:string;
next:pointer;
end;

procedure stackinc(var h:pointer;const x:string);
<<进栈
function stackdel(var h:pointer):pointer;
<<出栈返回栈顶结点,并摘除栈顶结点
procedure dispstack(var h:pointer);<<回收内存
implementation
procedure dispstack(var h:pointer);
var
p:pointer;
begin
while h^.next<>nildo
begin
p:=h;
h:=h^.next;
dispose(p);
end;
end;

procedure stackinc(var h:pointer;const x:string);
var
p:pointer;
begin
new(p);
p^.x:=x;
p^.next:=h;
h:=p;
end;

function stackdel(var h:pointer):pointer;
var
p:pointer;
begin
if h^.next=nil then
stackdel:=h
else
begin
p:=h;
h:=h^.next;
stackdel:=p;
end;
end;
end.

----------------------------------------------------------------------
procedure calcu(var t1,t2:pointer);
<<一次出栈计算
var
c:char;
x1,x2,x:integer;
begin
x:=0;
c:=stackdel(t2)^.x[1];
x1:=strtoint(stackdel(t1)^.x);
x2:=strtoint(stackdel(t1)^.x);
case c of
'+': x:=x1+x2;
'-': x:=x2-x1;
'/': x:=x2 div x1;
'*': x:=x1*x2;
end;
stackinc(t1,inttostr(x));
<<将结果进操作数栈
end;

function calculator(var t1,t2:pointer;const s:string):integer;<<扫描s表达式串,并返回结果,和pascal语法类似以';'为结束符
var
i,v:integer;
c:char;
begin
i:=1;
c:=s;
while c<>';'do
begin
case c of
'+','-' : begin
while (t2^.next<>nil) and (t2^.x<>'(')do
calcu(t1,t2);
stackinc(t2,c);
inc(i);
c:=s;
end;
'*','/' : begin
if (t2^.next<>nil) and ((t2^.x='*') or (t2^.x='/')) then
calcu(t1,t2);
stackinc(t2,c);
inc(i);
c:=s;
end;
'(' : begin
stackinc(t2,c);
inc(i);
c:=s;
end;
')' : begin
while t2^.x<>'('do
calcu(t1,t2);
stackdel(t2);
inc(i);
c:=s;
end;
'0'..'9': begin
v:=0;
repeat
v:=v*10+ord(c)-ord('0');
inc(i);
c:=s;
until (c<'0') or (c>'9');
stackinc(t1,inttostr(v));
end;
end;
end;
while t2^.next<>nildo
calcu(t1,t2);
calculator:=strtoint(t1^.x);
end;

---------------------------------------------
实际调用例子
procedure TForm1.Button1Click(Sender: TObject);
var
t1,t2:pointer;
i:integer;
begin
new(t1);<<操作数栈
t1.next:=nil;
new(t2);<<运算符栈
t2.next:=nil;
i:=calculator(t1,t2,edit1.Text);
edit2.Text:=inttostr(i);
dispstack(t1);
dispstack(t2);
end;

未做表达式正确性认证,自己稍微改一下就可了
 
多人接受答案了。
 
后退
顶部