求一看似简单的算法。(50分)

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

dana

Unregistered / Unconfirmed
GUEST, unregistred user!
在edit.text='1+2+3-4+50' 等于多少?(现在只考虑+,-就可以)
 
返回bool值
 
我有一个控件,很好用,你要不要
 
返回Bool是什么意思?
什么控件?
 
一般的加减乘除、开方等等都有
 
我要只是一个字符串,他有这些数据的计算,我们如何得出他的结果?
 
query.sql.add('select 1+2+3+6-12/4 from table');加减乘除括号随便用,绝招!
 
如果你只要加减的话,我可以给你写一个简单点的
 
mathparser
这是什么意思?
仙剑奇侠 ,你有什么高招,请赐教!
 
wlh_1,:你这个是什么意思,我没看明白。
 
See my code, can calculate + - * /.
type
EExpression = class(Exception);
TOperatorPriority = (opError, opLower, opSame, opHigher);
const
Operators = '+-*/()#';
OpPriority: array[1..7, 1..7] of TOperatorPriority = (
(opHigher, opHigher, opLower, opLower, opLower, opHigher, opHigher),
(opHigher, opHigher, opLower, opLower, opLower, opHigher, opHigher),
(opHigher, opHigher, opHigher, opHigher, opLower, opHigher, opHigher),
(opHigher, opHigher, opHigher, opHigher, opLower, opHigher, opHigher),
(opLower, opLower, opLower, opLower, opLower, opSame, opError ),
(opHigher, opHigher, opHigher, opHigher, opError, opHigher, opHigher),
(opLower, opLower, opLower, opLower, opLower, opError, opSame )
);
{ Math expression calculation }
{ Compare priority of between Op1 and Op2
Result
opLower: Op1's priority is lower than Op2's
opSame: Op1's priority is same as Op2's
opHigher: Op1's priority is higher than Op2's }
function ComparePriority(Op1, Op2: Char): TOperatorPriority;
var
I1, I2: Integer;
begin
Result := opError;
I1 := Pos(Op1, Operators);
I2 := Pos(Op2, Operators);
if (I1 > 0) and (I2 > 0) then
Result := OpPriority[I1, I2];
end;

function IsOperator(C: Char): Boolean;
begin
Result := Pos(C, Operators) > 0;
end;

procedure GetElement(var P: PChar;
var Optr: Char;
var Opnd: string);
function GetOperand(var P: PChar): string;
var
P0: PChar;
begin
P0 := P;
while (P^ <> #0) and not IsOperator(P^)do
Inc(P);
SetString(Result, P0, P - P0);
end;

function GetOperator(var P: PChar): Char;
begin
Result := P^;
Inc(P);
end;

begin
Optr := #0;
Opnd := '';
if IsOperator(P^) then
Optr := GetOperator(P) else
Opnd := GetOperand(P);
end;

function Operate(A, B:do
uble;
Optr: Char):do
uble;
begin
case Optr of
'+': Result := A + B;
'-': Result := A - B;
'*': Result := A * B;
'/': Result := A / B;
else
raise EExpression.CreateFmt('Invalid operate: %s', [Optr]);
end;
end;

function CalcExpr(const Expr: string): string;
var
OptrStack, OpndStack: TStack;
S, Opnd: string;
Optr,do
Optr: Char;
P: PChar;
OpndA, OpndB: ^Double;
begin
// '#' used as the terminator of expression
S := Expr + '#';
OptrStack := TStack.Create;
OpndStack := TStack.Create;
try
{ To decide whether expression has been calculated completely, we add a
'#' before calculation. When OptrStack left only one item '#', and the
last terminator '#' is reached, the calculation is over. }
OptrStack.Push(Pointer(Byte('#')));
P := PChar(S);
GetElement(P, Optr, Opnd);
while (Optr <> '#') or (Char(OptrStack.Peek) <> '#')do
begin
if Optr = #0 then
begin
GetMem(OpndA, SizeOf(Double));
OpndA^ := StrToFloat(Opnd);
OpndStack.Push(OpndA);
GetElement(P, Optr, Opnd);
end else
case ComparePriority(Char(OptrStack.Peek), Optr) of
opError:
raise EExpression.Create('Invalid expression');
opLower: // Priority is lower, so push Optr into OptrStack as the current
begin
// Operator
OptrStack.Push(Pointer(Byte(Optr)));
GetElement(P, Optr, Opnd);
end;
opSame: // Priority is same, this case only occurs parentheses '(', ')',
begin
// so simply Pop the '(' and discard it
OptrStack.Pop;
GetElement(P, Optr, Opnd);
end;
OpHigher: // Priority is higher, so pop and calculate (operandA operator
begin
// operandB), and push the result into OpndStack as an operand
do
Optr := Char(OptrStack.Pop);
OpndB := OpndStack.Pop;
OpndA := OpndStack.Pop;
OpndA^ := Operate(OpndA^, OpndB^,do
Optr);
OpndStack.Push(OpndA);
// OperandA is the result of Operate, can't free its memory
FreeMem(OpndB);
// OperandB is not used, free its memory
end;
end;
end;
{ OptrStack left the only operator '#', and OpndStack must only left one
item too, that's the expression result }
if OpndStack.Count <> 1 then
raise EExpression.Create('Invalid expression');
OpndA := OpndStack.Pop;
Result := FloatToStr(OpndA^);
FreeMem(OpndA);
finally
OptrStack.Free;
OpndStack.Free;
end;
end;
 
query.sql.add('select 1+2+3+6-12/4 from table');加减乘除括号随便用,绝招! 这是利用sql语句地特点计算公式地方法,当然使用变量也可以。值保存在制定地字段中,如果你不想写复杂地函数解析,那么这是一个最好地方法!
 
mathparser是一个控件
如果不用控件,就自己写一个公式解释器呗
 
wlh_1,还是搞不清楚你说的,是不是题目没理解清楚?
仙剑奇侠,你那个过程也太长了,也看不明白是什么意思
 
你没有用过sql语句吗?我写地很清楚啊!直接计算出结果来!你去机子上试一试呀。如果你没有用过sql,那我晕!
 
我自己编了一个表达式运算库,是dll的,目前支持普通的+-*/和(运算符,要的话留mail
 
shdzdn@126.com
或者dana163@163.net
 
最后还是自已搞定了.
 
后退
顶部