用物件導向方法解決24點問題

2021-04-17 06:35:06 字數 4816 閱讀 9945

計算24點,可以抽象描述為:求代數系統的子系統的所有運算結果為24的運算。一般情況下有很多性質,如交換律,i+j=j+i,結合律,i+(j+k)=(i+j)+k等等,為了使我這個惰人寫**方便,我去掉所有規律(這樣使運算量加幾倍了,呵呵,相信可以用來烤機了),並加上乙個一元運算子~,~i=i i屬於sinteger,再加上乙個似乎破壞了數學完美性的規則,sinteger中的元素在乙個運算中只能用一次,如果不加這個"所有運算"將會是乙個無限集.

第三代語言不能直接操作集合,所以要作一下轉化,想辦法把作用在代數系統<;+,-,*,/>的所有運算(a+b*c,a-b*c,a+b/c,(a+b)*c........)用別的方法表示。

下面我用o表示二元運算子,oi表示第i個二元運算子。用[<,};oi>]表示,也就是返回作用在集合,笛卡爾積上的運算結果。

[<;~>]表示,也就是返回作用在集合上的運算結果。記得上面我去掉了很多性質嗎,所以可能a+b不等於b+a,因此我要把a+b+c與c+a+b都要計算一次,而不是推出來.下面是用[<,; >]描述"作用在代數系統<;+,-,*,/>的所有運算".

[<[<;~>],[<[<;~>],[<;~>];oi>];oi>]

[<[<;~>],[<[<;~>],[<;~>];oi>];oi>]

[<[<;~>],[<[<;~>],[<;~>];oi>];oi>]

[<[<;~>],[<[<;~>],[<;~>];oi>];oi>]

[<[<;~>],[<[<;~>],[<;~>];+,->];+,->]=

[<[<;~>],[<,;+,->];+,->]=

[<[<;~>],;+,->]=

[<,;+,->]=

是不是發現很多重複,可能我上面說的運算量加幾倍了太保守了,最起碼也是個代數級數式的增加.

經過一輪對數學世界的破壞,終於使問題對計算機來說簡化了。

記得上一次上數學課都是兩年前了,不知上面的內容表達得是否正確。

上面很多地方提到集合,第三代語言操作集合的最有效方法當然是使用itertor模式,所以先定義乙個titerator基類,以後的集合都是它的子類。

觀察[<,; >],它由三部分組成(一元運算只有二部分),逗號左邊,逗號右邊,分號右邊,其中逗號左右都是乙個[<,; >],分號右邊是運算子,現在把[<,; >]轉化為乙個類tnode.分號右邊是一系列運算子,因此使用toperatoriterator表示。

我是用[<,; >]描述"作用在代數系統<;+,-,*,/>的所有運算".觀察上面,「代數系統<;+,-,*,/>的所有運算」是由多個[<,; >]的並集表示,因此又需要乙個titerator,命名為ttreeiterator.下面就是用modelmaker 6.2繪製的類圖

其中的ttreebuilder是用來構建tnode的,如建立乙個:[<[<;~>],[<[<;~>],[<;~>];oi>];oi>]

iclientinte***ce是乙個最小化的介面,大部分二次開發的人員都不會想與複雜的內部結構打交道。

做到這裡時我就想描述內部的工作流,活**是一種不錯的方法,考慮到rup的開發方式(主要是我只會一點點uml),所以決定還是先畫個順序圖,可是畫完順序圖後,**就寫出來了,可能這個問題過於簡單,有機會我想找個複雜的問題。順序圖中我用了一些不太標準的表示方法,用來描述函式的返回。

(為了整體布局,我把圖縮小了,有點失真,請用看圖工具開啟這張圖)

這是乙個取[<,; >]中所有計算結果的順序圖。actor首先通知tnode重新開始(resume),跟著取第乙個運算的運算結果(eventuate,中的a+(b+c) ),再用evaluate評估是否還有表示式(當還有運算子時,代表還有表示式,當然首先要檢查逗號兩邊的[<,; >],如果它們有表示式,哪一定就是有表示式存在,沒必要看當前是否還有運算子),如果有評估為真,哪繼續用eventuate取結果。「繼續」寫起來容易,但畫就難了,我在modelmaker中找不到相應迴圈符號,所以用了一條豎線表示範圍,用文字表示退出條件。

下面是我對著這個圖寫出來的怪怪**:

function tnode.evaluate: boolean;

varleftbool, rightbool: boolean;

begin

result:=false;

if (fleftchild=nil) and (frightchild=nil) then

begin

result:=not foperatoriterator.isdone;

if result then

foperatoriterator.next;

exit;

end;

leftbool:=fleftchild.evaluate;

if leftbool then

begin

result:=true;

exit;

end;

rightbool:=frightchild.evaluate;

if rightbool then

begin

fleftchild.resume;

result:=true;

exit;

end;

if not foperatoriterator.isdone then

begin

foperatoriterator.next;

fleftchild.resume;

frightchild.resume;

result:=true;

exit;

end;

end;

是不是感覺怪怪的。

(fleftchild=nil) and (frightchild=nil)這句檢測這是否乙個只有一元運算子的[<; >]。

看到這裡,大家應該明白它們之間的對應關係了吧

"作用在代數系統<;+,-,*,/>的所有運算(別忘了加上乙個破壞規則,)"是乙個很大的集合,

分成多個子集,分別為

+,-,*,/作用有元組(a,b,c)上

+,-,*,/作用有元組(a,c,b)上

+,-,*,/作用有元組(b,a,c)上

再從這些子集中把每個元素提取出來。

+,-,*,/作用有元組(a,b,c)上用tnode表示,哪全集用ttreeiterator表示,下面就是與它相關的順序圖

function tclientinte***ce.getanswer(anumarr:intarray): tstringlist;

varfresult:tstringlist;

ti: ttreeiterator;

nd: tnode;

num:double;

function getresult:tstringlist;

begin

if not assigned(fresult) then

fresult:=tstringlist.create;

result:=fresult;

end;

begin

fresult:=nil;

ti:=ttreeiterator.create(anumarr);

ti.first;

while true do

begin

nd:=ti.currentitem;

nd.resume;

repeat

trynum:=nd.eventuate;

if tcheck.check(num) then

getresult.add(nd.print+'='+floattostr(num));

except

//捕捉零除異常

end;

until (not nd.evaluate);

if ti.isdone then break;

ti.next ;

end;

result:=fresult;

end;

actor從ttreeiterator中取乙個子集,再取子集的所有元素,取完元素後,再取乙個子集一直迴圈下去。

可能大家看完一本uml書後,也找不到幾個資源釋放的字樣,這應該是技術發展的走勢,就像今天沒人會考慮640的限制,所以我在**裡也沒寫這部分,我希望學習的是未來的技術。

更改了源**後一定要按以保持與model的同步,如果忘記了可能會見到這個對話方塊

這時最好按no,如是按了yes,可能你在delphi中辛苦寫的**就被刪了。如果覺得經常用refresh in model很煩,可以在下面這裡保持同步

2.這應該是乙個bug

modelmaker中的組合與聚合關係竟然是一樣的線,要注意一下,別理解錯誤了.

3.又是乙個bug

modelmaker中的singleton模式竟然產生錯誤**,我本來想在tmonitor使用這個模式。

class function tform1.accessinstance(request: integer): tform1;

const finstance: tform1 = nil;

begin

case request of

0 : ;

1 : if not assigned(finstance) then finstance := createinstance;

2 : finstance := nil;

else

raise exception.createfmt('illegal request %d in accessinstance',

[request]);

end;

result := finstance;

end;

modelmaker帶的設計模式不多,也是一大缺陷。pascal語言似乎沒意增加,操作符過載這兩個有用的特性,哪設計模式的使用量相信將會增加,modelmake應該增強這一點。

php 物件導向之解決單繼承問題

在編寫低耦合 時,有時可能會盡量將不同型別方法放置與不同類中方便維護,但是同時我們可能某乙個物件所擁有的屬性和方法集合不同的類屬性和方法,但是 php 只有單繼承,無法通過extends 繼承多個父類來共享多個類的屬性和方法,不過雖然沒有但是我們可以通過一下 第一種方法,採用php 魔術方法 cal...

軟考知識點梳理 物件導向方法

物件導向 object oriented,oo 方法認為,客觀世界是由各種物件組成的,任何事物都是物件,每乙個物件都有自己的運動規律和內部狀態,都屬於某個物件類,是該物件類的乙個元素。複雜的物件可由相對簡單的各種物件以某種方式而構成,不同物件的組合及相互作用就構成了系統。oo方法 是當前的主流開發方...

用物件導向的方法重寫選項卡

面向過程的tab選項卡 內容1內容2 內容3下面我們要把它改成物件導向的選項卡 oli i onclick function 將onclick後面的匿名函式提到外面去 oli i onclick tab function tab adiv this.index style.display block...