如何将一组字符串进行数字计算(50分)

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

wqh0329

Unregistered / Unconfirmed
GUEST, unregistred user!
如:字符串20+8*15+30*1
在edit1中输入20+8*15+30*1
在edit2中得到170
 
只能自己分析了
 
我在FOXBASE玩过这一套。
string逐个字符扫描,给COMPUTR来个人工智能。
是0-9是数字,连续几个是0-9是数字。
是+-/*是计算符号。
很复杂的逻辑判断。
 
《数据结构》课本在讲述堆栈时有一个表达式计算的现成例子啊。
 
wjiachun说得对,现在很多学生的毕业设计就是做一个计算器程序,
这种程序是能够体现一个人编程的基本功,如果再加上括号及其他什么功能就更复杂
一些,自己想吧,不要怕麻烦
 
BaKuBaKu是对的。
利用算符优先算法可以很容易的做这种表达式求值的程序。
原理是用两个堆栈,一个放数字,一个放算符。
具体你参考一下那本书吧。如果需要我贴出算法来也可以,不过有灌水之嫌了。
 
看看数据结构的堆栈那一章就明白啦
 
with tmpQuery do
begin
databasename:=...
sql.text:='select '+edit1.text+' from dual';
open;
edit2.text:=fields[0].asString;
Free;
end;

以上是针对oracle
对其它也有相应的 方法
 
這個問題不是很難﹐但做起來比較麻煩﹐而且在運算邏輯方面要考慮全面。你可以在程序中
先不允許輸入除了'+','-','/','*','(',')'等字符外的其它字符﹐然后再對其做相應的運
算﹐就行了。但寫起來的確很麻煩。不過﹐你能將這個程序搞清楚而沒有問題﹐那么對你的
程序思維邏輯方面會有很大進步的。
 
来自:jqw 时间:00-10-23 10:51:35 ID:373285
with tmpQuery do
begin
databasename:=...
sql.text:='select '+edit1.text+' from dual';
open;
edit2.text:=fields[0].asString;
Free;
end;

以上是针对oracle
对其它也有相应的 方法
======================================
同意,
如果你只想获得结果的话。

BTW:
sql.text:='select '+edit1.text+' from dual';
可以改为
<font color=red> sql.text:='select '+edit1.text';</font>
 
看看数据结构的书吧, 用两个堆栈, 先将正则表达式转成逆波兰式,
然后就简单了.
 
又是这种老问题!
自己将它分成数字和表达式,然后进行逆波兰转换。
 
其实,我的方法是最简单的
 
如果是其它数据库,
try the following:

with tmpQuery do
begin
databasename:=...
sql.text:='select '+edit1.text+' from 你的系统中任何一个表名';
open;
edit2.text:=fields[0].asString;
Free;
end;
 
各位朋友,你们给我的email我已经看过了.非常感谢你们,但是,你们提到的运用堆栈方面
方法,我看了数据结构这本书,并且也看到了范例,但是无用.还请各位朋友具体指点一二.
 
问题解决就行啦

堆栈-->头疼
 
噫,逆波兰式很容易就可以解决啊
也很简单嘛,难道你跟我的同学一样
看到堆栈就头疼(同时对jqw说)?
我可是会计班的.
 
这是我以前写的,为了在ActiveX中用,所以用了Variant变量。
你把它改成Char后者String都可以。
function precede(op1,op2:Variant):Char;
begin
if (op1='+') or (op1='-') then begin
if op2='+' then precede:='>';
if op2='-' then precede:='>';
if op2='*' then precede:='<';
if op2='/' then precede:='<';
if op2='%' then precede:='<';
if op2='^' then precede:='<';
if op2='(' then precede:='<';
if op2=')' then precede:='>';
if op2='#' then precede:='>';
end;
if (op1='*') or (op1='/')or(op1='%')then begin
if op2='+' then precede:='>';
if op2='-' then precede:='>';
if op2='*' then precede:='>';
if op2='/' then precede:='>';
if op2='%' then precede:='>';
if op2='^' then precede:='<';//乘方运算符级别较高
if op2='(' then precede:='<';
if op2=')' then precede:='>';
if op2='#' then precede:='>';
end;
if op1='^' then begin
if op2='+' then precede:='>';
if op2='-' then precede:='>';
if op2='*' then precede:='>';
if op2='/' then precede:='>';
if op2='%' then precede:='>';
if op2='^' then precede:='>';
if op2='(' then precede:='<';
if op2=')' then precede:='>';
if op2='#' then precede:='>';
end;
if op1='(' then begin
if op2='+' then precede:='<';
if op2='-' then precede:='<';
if op2='*' then precede:='<';
if op2='/' then precede:='<';
if op2='%' then precede:='<';
if op2='^' then precede:='<';
if op2='(' then precede:='<';
if op2=')' then precede:='=';
if op2='#' then precede:='E';
end;
if op1=')' then begin
if op2='+' then precede:='>';
if op2='-' then precede:='>';
if op2='*' then precede:='>';
if op2='/' then precede:='>';
if op2='%' then precede:='>';
if op2='^' then precede:='>';
if op2='(' then precede:='E';
if op2=')' then precede:='>';
if op2='#' then precede:='>';
end;
if op1='#' then begin
if op2='+' then precede:='<';
if op2='-' then precede:='<';
if op2='*' then precede:='<';
if op2='/' then precede:='<';
if op2='%' then precede:='<';
if op2='^' then precede:='<';
if op2='(' then precede:='<';
if op2=')' then precede:='E';
if op2='#' then precede:='=';
end;
end;

function operate(a,theta,b:Variant):Variant;
var
c:Variant;
i:integer;
begin
if theta='+' then operate:=a+b;
if theta='-' then operate:=a-b;
if theta='*' then operate:=a*b;
if theta='/' then operate:=a/b;
if theta='^' then begin
c:=a;
for i:=2 to Round(b) do operate:=a*c;
end;
end;
 
相当于自己做个计算器。
既然是在本栏目提出的问题,那么你肯定是在使用数据库,用sql查询语句就可以实现(只要
公式表达式不是太复杂)。
'select 表达式 as result';
比如:query1.sql.text:='select 23+5 as result';
query1.open;
返回结果:
query1['result']=28;
 
以前回答另一位仁兄的程序,功能是计算字符串表达式的值.
支持加,减,乘,除,括号和百分号.例如(2*3)% 的结果是0.06
interface
uses SysUtils;
var
Ca_err:boolean;

Function Do_Calculate(s:string):Extended;

implementation
var
Ca_token:char;
Ca_exp:string;
Ca_CurPos,Ca_Len:integer;

function term:Extended;forward;
function factor:Extended;forward;

procedure error;
begin
Ca_err:=true;
raise Exception.Create('错误的表达式!');
end;

function GetNextChar:char;
begin
if Ca_CurPos=Ca_Len then Result:=#0
else
begin
inc(Ca_CurPos);
Result:=Ca_exp[Ca_CurPos];
end;
end;

procedure match(expectedToken:Char);
begin
if Ca_token=expectedToken then Ca_token := GetNextChar
else Ca_err := true;
end;

function exp:Extended ;
var temp:Extended;
begin
if not Ca_err then
begin
temp:=term;
while (Ca_token='+') or (Ca_token='-') do
case (Ca_token) of
'+':begin
match('+');
temp:=temp+term;
end;
'-':begin
match('-');
temp:=temp-term;
end;
end; //case
Result:=temp;
end;
end;

function term:Extended;
var temp:Extended;
begin
if not Ca_err then
begin
temp:=factor;
while (Ca_token='*') or (Ca_token='/') do
case (Ca_token) of
'*':begin
match('*');
temp:=temp*factor;
end;
'/':begin
match('/');
temp:=temp/factor;
end;
end; //case
result:=temp;
end;
end;

function FindNum:Extended;
var s:string;
begin
if not Ca_err then
begin
s:=Ca_token;
Ca_token := GetNextChar;
while Ca_token in ['0'..'9'] do
begin
s:=s+Ca_token;
Ca_token := GetNextChar;
end;
if Ca_token='.' then
begin
s:=s+'.';
Ca_token := GetNextChar;
while Ca_token in ['0'..'9'] do
begin
s:=s+Ca_token;
Ca_token := GetNextChar;
end;
end;
Result:=StrToFloat(s);
if Ca_token='%' then
begin
match('%');
Result:=Result/100;
Ca_token := GetNextChar;
end;
end;
end;

function factor:Extended ;
var temp:Extended;
begin
if not Ca_err then
if Ca_token='(' then
begin
match('(');
temp := exp;
match(')');
end
else if (Ca_token in ['0'..'9']) then
begin
temp:=FindNum;
end
else error;
Result:=temp;
end;

Function Do_Calculate(s:string):Extended;
begin
Ca_CurPos:=0;
Ca_err:=false;
Ca_exp:=s;
Ca_Len:=length(s);
Ca_token:=GetNextChar;
Result:=exp;
if Ca_CurPos<>Ca_Len then error;
end;
end.

用法:
Edit2.Text:=FloatToStr(Do_Calculate(Edit1.Text));
 
后退
顶部