全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2022
推到 Plurk!
推到 Facebook!

後序式求值

尚未結案
Kevin051
一般會員


發表:3
回覆:3
積分:1
註冊:2008-01-07

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-04-10 20:05:58 IP:122.127.xxx.xxx 訂閱
AB C*DE/-(假設運算元值分別是2,5,4,6,3) 答案是26 要如何把結果顯示在Memo1裡面 最好有過程 麻煩幫我看一下 謝謝(附上我目前做的程式)
附加檔案:47fe02a6c68d8_作業.rar
編輯記錄
Kevin051 重新編輯於 2008-04-10 20:09:52, 註解 無‧
Kevin051 重新編輯於 2008-04-11 11:42:30, 註解 無‧
Kevin051 重新編輯於 2008-04-11 11:42:39, 註解 無‧
Kevin051 重新編輯於 2008-04-11 11:43:35, 註解 無‧
Kevin051 重新編輯於 2008-04-11 11:43:44, 註解 無‧
cobraliu
中階會員


發表:15
回覆:75
積分:83
註冊:2007-11-22

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-04-10 21:20:50 IP:220.143.xxx.xxx 訂閱
怎麼...@@...突然你們同學功課出現...@@
而你的Source...壓縮有問題...

http://delphi.ktop.com.tw/board.php?cid=30&fid=1498&tid=93229

===================引 用 Kevin051 文 章===================
AB C*DE/-(假設運算元值分別是2,5,4,6,3) 答案是26 要如何把結果顯示在Memo1裡面 最好有過程 麻煩幫我看一下 謝謝(附上我目前做的程式)
------
初學、初學、學了很久...還是在初學階段..Orz
編輯記錄
cobraliu 重新編輯於 2008-04-10 21:21:25, 註解 無‧
Kevin051
一般會員


發表:3
回覆:3
積分:1
註冊:2008-01-07

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-04-11 11:45:48 IP:218.163.xxx.xxx 訂閱
壓縮沒問題呀 Delphi程式裡頭要怎麼計算 2 5*4-6/3=26 然後寫入memo1裡 有可能嗎
編輯記錄
Kevin051 重新編輯於 2008-04-11 11:47:42, 註解 無‧
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-04-11 14:08:48 IP:210.242.xxx.xxx 訂閱
memo1.Lines.Add(inttostr(strtoint(stack.items[1])+(strtoint(stack.items[2])*strtoint(stack.items[3]))-round(strtoint(stack.items[4])/strtoint(stack.items[5]))));
是這樣嗎???
編輯記錄
shinhrn 重新編輯於 2008-04-11 15:41:04, 註解 無‧
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-04-11 17:07:01 IP:123.193.xxx.xxx 未訂閱
2+5*4-6/3=20
(2 5)*4-6/3=26

以下程式碼, 提供你研究.....

[code delphi]
unit fMain;

interface

uses
Classes, Controls, Forms, ExtCtrls, Menus, StdCtrls, Contnrs;

type

{ TTokenType }
TTokenType = (tokNUMBER, tokOPERATOR, tokEQUALS);

{ TToken }
TToken = class(TPersistent)
private
_Type_: TTokenType; //表示Token型態
OpSign: Char; //表示運算子符號
Number: Double; //表示運算元數值
function Priority: Integer;
public
constructor Create;
end;

{ TTokenizer }
TTokenizer = class(TPersistent)
private
FList: TStringList;
procedure Clear;
public
constructor Create;
destructor Destroy; override;
function Tokenize(S: string): Boolean;
end;

{ TEvaluator }
TEvaluator = class(TPersistent)
protected
Opd, Opt: TStack;
FTokenizer: TTokenizer;
function IsHigher(Priority: Integer): Boolean;
function IsLessOrEqual(Priority: Integer): Boolean;
function DO_ACTION(Opt, Opd: TStack): Boolean;
procedure DO_CLEAR(Opt, Opd: TStack);
public
constructor Create;
destructor Destroy; override;
function Calc(S: string): Double;
end;

{ TfrmMain }
TfrmMain = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
public
end;

{ Public Function }
function PriorityIs(c: Char): Integer;
function IsOperator(c: Char): Boolean;
function IsDigit(c: Char): Boolean;
function IsValid(c: Char): Boolean;

var
frmMain: TfrmMain;

implementation

uses SysUtils, Math;

{$R *.dfm}

function IsDigit(c: Char): Boolean;
begin
Result := c in ['0'..'9'];
end;

function IsOperator(c: Char): Boolean;
begin
Result := c in ['(',')',' ','-','*','/'];
end;

function IsValid(c: Char): Boolean;
begin
Result := IsDigit(c) or IsOperator(c) or (c='=');
end;

function PriorityIs(c: Char): Integer;
begin
Result := -1;//ERROR
case c of
'(': Result := 0;
')': Result := 1;
' ','-': Result := 2;
'*','/': Result := 3;
end;
end;

{ TToken }

constructor TToken.Create;
begin
inherited;
_Type_ := tokNUMBER;
OpSign := #0;
Number := 0;
end;

function TToken.Priority: Integer;
begin
Result := PriorityIs(OpSign);
end;

{ TTokenizer }

procedure TTokenizer.Clear;
var
I: Integer;
begin
for I := 0 to FList.Count-1 do
FList.Objects[I].Free;
FList.Clear;
end;

constructor TTokenizer.Create;
begin
inherited;
FList := TStringList.Create;
end;

destructor TTokenizer.Destroy;
begin
Clear;
inherited;
end;

function TTokenizer.Tokenize(S: string): Boolean;
var
p: string;
I: Integer;
T: TToken;
begin
Clear;

I := 1;
while I <= Length(S) do
begin
p := '';
if IsValid(S[I]) then
begin
//判斷是否為運算元
if IsDigit(S[I]) then
begin
T := TToken.Create;//產生一個新的
try
while (I<=Length(S)) and IsDigit(S[I]) do
begin
p := p S[I];
T._Type_ := tokNUMBER;
T.Number := StrToFloatDef(p, T.Number);
Inc(I);
end;
finally
if T <> nil then FList.AddObject('', T);
end;
end;

if IsOperator(S[I]) then
begin
T := TToken.Create;//產生一個新的
try
T._Type_ := tokOPERATOR;
T.OpSign := S[I];
finally
if T <> nil then FList.AddObject('', T);
end;
end
//判斷是否為等號
else if (S[I] = '=') then
begin
T := TToken.Create;//產生一個新的
try
T._Type_ := tokEQUALS;
finally
if T <> nil then FList.AddObject('', T);
end;
end;
end;
Inc(I);
end;
Result := FList.Count > 0;
end;

{ TEvaluator }

constructor TEvaluator.Create;
begin
inherited;
FTokenizer := TTokenizer.Create;
opd := TStack.Create;
Opt := TStack.Create;
end;

destructor TEvaluator.Destroy;
begin
FreeAndNil(opd);
FreeAndNil(opt);
FreeAndNil(FTokenizer);
inherited;
end;

function TEvaluator.IsHigher(Priority: Integer): Boolean;
begin
Result := False;
if Opt.Count > 0 then
Result := Priority > TToken(TObject(Opt.Peek)).Priority;
end;

function TEvaluator.IsLessOrEqual(Priority: Integer): Boolean;
begin
Result := False;
if Opt.Count > 0 then
Result := not IsHigher(Priority);
end;

function TEvaluator.Calc(S: string): Double;
var
I, C: Integer;
T: TToken;
begin
try
FTokenizer.Tokenize(S);
try
with FTokenizer do
begin
C := FList.Count;
for I := 0 to C-1 do
begin
T := TToken(FList.Objects[I]);
if T._Type_ = tokEQUALS then Break;
case T._Type_ of
tokNUMBER : opd.Push(T);
tokOPERATOR :
begin
//'2 5*4-6/3='
if (T.Priority <> 0) and not IsHigher(T.Priority) then
while IsLessOrEqual(T.Priority) do
DO_ACTION(Opt, Opd);
Opt.Push(T);
end;
else begin
//ERROR;
Break;
end;
end;
end;
end;
DO_CLEAR(Opt, Opd);
Result := TToken(Opd.Pop).Number;
finally
FTokenizer.Clear;
end;
finally
FreeAndNil(Opd);
FreeAndNil(Opt);
end;
end;

function TEvaluator.DO_ACTION(Opt, Opd: TStack): Boolean;
var
sign: Char;
T1, T2: TToken;
begin
Result := True;
sign := TToken(Opt.Peek).OpSign;
case sign of
' ','-','*','/':
begin
T1 := TToken(opd.Pop);
T2 := TToken(opd.Pop);
case sign of
' ': T1.Number := T1.Number T2.Number;
'-': T1.Number := T2.Number - T1.Number;
'*': T1.Number := T2.Number * T1.Number;
'/':
if T1.Number <> 0 then
T1.Number := T2.Number / T1.Number
else begin
{ 除以零錯誤 }
Result := False;
end;
end;
Opd.Push(T1);
end;
'(',')':;
end;
Opt.Pop;
end;

procedure TEvaluator.DO_CLEAR(Opt, Opd: TStack);
begin
while(Opt.Count > 0) do DO_ACTION(Opt, Opd);
end;

procedure TfrmMain.Button1Click(Sender: TObject);
var
O: TEvaluator;
V: Double;
begin
O := TEvaluator.Create;
try
V := O.Calc('(2 5)*4-6/3=');
finally
FreeAndNil(O);
end;
Label1.Caption := Format('%f', [V]);
end;

end.
[/code]
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-04-11 17:14:09 IP:123.193.xxx.xxx 未訂閱
測試碼下載:

http://delphi.ktop.com.tw/download.php?download=upload/47ff2bb37c46c_Test062.zip

附加說明: 這是書上的範例, 我只是用物件的方法將它實作出來而已....
編輯記錄
jow 重新編輯於 2008-04-11 17:47:11, 註解 無‧
Kevin051
一般會員


發表:3
回覆:3
積分:1
註冊:2008-01-07

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-04-11 18:54:59 IP:218.163.xxx.xxx 訂閱

===================引 用 jow 文 章===================
述刪
看了你貼的程式碼後 大概有了個方向 知道該怎麼做了 感激不盡
系統時間:2024-05-06 9:35:01
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!