共找到303种
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Memo1: TMemo;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
function ParExpr(const Tkens: String;
var Fail: Boolean): Integer;
end;
var
Form1: TForm1;
oPrioritys: array[1..5, 1..5] of Integer = (
// +, -, *, /, _,
{+} (0, 0,-1,-1,-1),
{-} (0, 0,-1,-1,-1),
{*} (1, 1, 0, 0,-1),
{/} (1, 1, 0, 0,-1),
{_} (1, 1, 1, 1, 0)
);
function IdOfOp(C: Char): Integer;
function ValueOf(C: Char): Integer;
function PrioOfOp(C1, C2: Integer): Integer;
function Calc(N1, N2: Integer;
C: Integer;
var Fail: Boolean): Integer;
function TrimExpr(var S: String): Boolean;
implementation
{$R *.dfm}
function TrimExpr(var S: String): Boolean;
var
m: String;
i: Integer;
ct: Integer;
begin
Result := False;
m := S;
ct := 0;
for i := 1 to Length(m)do
begin
if m <> '_' then
begin
ct := ct + 1;
if Result then
begin
S[ct] := m;
end;
end
else
begin
Result := True;
end;
end;
if Length(m) <> ct then
SetLength(S, ct);
end;
function IdOfOp(C: Char): Integer;
begin
case C of
'+': Result := 1;
'-': Result := 2;
'*': Result := 3;
'/': Result := 4;
'_': Result := 5;
else
Result := 0;
end;
end;
function ValueOf(C: Char): Integer;
begin
if C in ['0'..'9'] then
Result := Ord(C) - Ord('0')
else
Result := -1;
end;
function PrioOfOp(C1, C2: Integer): Integer;
begin
if (C1 > 0) and (C2 > 0) then
Result := oPrioritys[C1, C2]
else
Result := 0;
end;
function Calc(N1, N2: Integer;
C: Integer;
var Fail: Boolean): Integer;
var
m1, m2: Integer;
n: Integer;
begin
m1 := N1;
m2 := N2;
n := C;
Result := 0;
case n of
1: Result := m1 + m2;
2: Result := m1 - m2;
3: Result := m1 * m2;
4:
begin
if (m2 = 0) then
Fail := True
else
Result := m1 div m2;
end;
5: Result := m1 * 10 + m2;
else
raise Exception.Create('invalidoperator');
end;
end;
function TForm1.ParExpr(const Tkens: String;
var Fail: Boolean): Integer;
var
i: Integer;
stk: array[0..20] of Integer;
//数据栈
opstk: array[0..20] of Integer;
//运算符栈
sp1, sp2: Integer;
op, lastop: Integer;
t, n1, n2: Integer;
begin
//解析表达式,假设每个符号或数字都是一个字符
sp1 := 0;
sp2 := 0;
n1 := 0;
n2 := 0;
for i := 1 to Length(Tkens)do
begin
t := ValueOf(Tkens);
if t >= 0 then
begin
//数字入栈
stk[sp1] := t;
sp1 := sp1 + 1;
end
else
//如果不是数字,则认为是运算符
begin
lastop := IdOfOp(Tkens);
if sp2 > 0 then
begin
op := opstk[sp2 - 1];
//循环,直到所有前面的运算都完成
if PrioOfOp(op, lastop) >= 0 then
begin
while (sp2 > 0) and (PrioOfOp(op, lastop) >= 0)do
begin
sp2 := sp2 - 1;
if sp1 > 0 then
begin
sp1 := sp1 - 1;
n2 := stk[sp1];
end;
if sp1 > 0 then
begin
sp1 := sp1 - 1;
n1 := stk[sp1];
end;
t := Calc(n1, n2, op, Fail);
stk[sp1] := t;
sp1 := sp1 + 1;
op := opstk[sp2 - 1];
end;
//运算符入栈
opstk[sp2] := lastop;
sp2 := sp2 + 1;
end
else
begin
opstk[sp2] := lastop;
sp2 := sp2 + 1;
end;
end
else
//符号入栈
begin
opstk[sp2] := lastop;
sp2 := sp2 + 1;
end;
end;
end;
while sp1 > 1do
begin
sp1 := sp1 - 1;
n2 := stk[sp1];
sp1 := sp1 - 1;
n1 := stk[sp1];
if sp2 > 0 then
begin
sp2 := sp2 - 1;
op := opstk[sp2];
stk[sp1] := Calc(n1, n2, op, Fail);
sp1 := sp1 + 1;
end;
end;
Result := stk[0];
end;
procedure TForm1.Button1Click(Sender: TObject);
const
ops: String = '+-*/_';
var
m: array[1..20] of Integer;
st: Integer;
t, v: String;
tc, pc: Integer;
t1, t2, n: Integer;
Fail: Boolean;
begin
//ShowMessage(IntToStr(ParExpr(Edit1.Text)));
//for test
t := '1,2,3,4,5,6,7,8,9';
Memo1.Lines.begin
Update;
Memo1.Lines.Clear;
t1 := GetTickCount;
for st := 1 to 20do
m[st] := 1;
st := 1;
tc := 0;
pc := 0;
while m[st] <= 5do
begin
t[st * 2] := ops[m[st]];
st := st + 1;
if st > 8 then
begin
tc := tc + 1;
Fail := False;
n := ParExpr(t, Fail);
if not Fail and (n = 100) then
begin
v := t;
TrimExpr(v);
Memo1.Lines.Add(v);
pc := pc + 1;
end;
st := st - 1;
m[st] := m[st] + 1;
while (st > 1)and (m[st] > 5)do
begin
m[st] := 1;
st := st - 1;
m[st] := m[st] + 1;
end;
end;
Application.ProcessMessages;
if Application.Terminated then
Break;
end;
t2 := GetTickCount;
Memo1.Lines.EndUpdate;
Caption := Format('%d/%d, Time: %d', [pc, tc, t2-t1]);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
s: String;
begin
s := '13_32_34';
TrimExpr(s);
ShowMessage(s);
end;
procedure TForm1.Button3Click(Sender: TObject);
var
m: Integer;
n: Boolean;
begin
n := False;
m := ParExpr(Edit1.Text, n);
if n then
Caption := 'fail'
else
Caption := IntToStr(m);
end;
end.