![VFP 愛用者社區 首頁](templates/subSilver/images/vfps.jpg) |
VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
|
上一篇主題 :: 下一篇主題 |
發表人 |
內容 |
朱育興
註冊時間: 2003-08-25 文章: 661 來自: 台中市大里區
第 1 樓
|
發表於: 星期六 十二月 20, 2003 2:59 pm 文章主題: 遞迴函數的應用--組合求解之應用1 |
|
|
* 這是動感游標論壇的「智力比拚」所出的題目
* 為求排版美觀,空白為全形空白,若要測試請將全形空白改為半形空白
* -------------------------------------------------- *
* 題目:某鐵路上共有10個車站,問需要準備幾種車票?
* 1.類似這種問題,我曾發表過 3 篇,我把它稱之為
* 「遞迴函數的應用」
* 2.這個問題我是參考我的「遞迴函數的應用」之第一篇的
* 組合求解改寫的
* 2003.12.20 YSC E-MAIL: y5096@ms23.hinet.net
* -------------------------------------------------- *
CLEAR ALL
CLOSE ALL
M_cSetEscape = SET("ESCAPE")
SET ESCAPE OFF
__Esc = .F.
__IsCalc = .F. && 是否正在計算中
M_nTran = "99,999,999,999,999,999,999,999,999,999"
WW_oMESSAGEBOX = CREATEOBJECT("UserForm1")
WITH WW_oMESSAGEBOX
.spinNum.Value = 10
.Show
ENDWITH
IF VARTYPE(WW_oMESSAGEBOX) = "O"
IF !ISNULL(WW_oMESSAGEBOX)
WW_oMESSAGEBOX.Release
ENDIF
ENDIF
SET ESCAPE &M_cSetEscape
CLEAR ALL
CLOSE ALL
RETURN
* ---------- DEFINE CLASS ---------- *
DEFINE CLASS UserForm1 AS Form
AutoCenter = .T.
BackColor = RGB(0,128,192)
BorderStyle = 3
Closable = .F.
DoCreate = .T.
FontName = "細明體"
FontSize = 12
ForeColor = RGB(255,255,255)
KeyPreview = .T.
MaxButton = .F.
MinButton = .F.
ShowTips = .T.
ShowWindow = 1
Top = 100
WindowState = 0
WindowType = 1
Width = 450
Height = 165
Caption = "鐵路上共有 N 個車站"
ADD OBJECT (SYS(2015)) AS LABEL WITH;
AutoSize = .T.,;
BackStyle = 0,;
Caption = "請輸入共有",;
ForeColor = RGB(255,255,255),;
FontName = "細明體",;
FontSize = 12,;
Left = 15,;
Top = 27
ADD OBJECT spinNum AS SPINNER WITH;
FontName = "細明體",;
FontSize = 11,;
Format = "RK",;
Height = 23,;
InputMask = "99",;
KeyboardHighvalue = 99,;
KeyboardLowvalue = 2,;
Left = 100,;
SpinnerHighvalue = 99,;
SpinnerLowvalue = 2,;
Top = 25,;
Width = 60
ADD OBJECT (SYS(2015)) AS LABEL WITH;
AutoSize = .T.,;
BackStyle = 0,;
Caption = "個車站",;
ForeColor = RGB(255,255,255),;
FontName = "細明體",;
FontSize = 12,;
Left = 165,;
Top = 27
ADD OBJECT (SYS(2015)) AS LABEL WITH;
AutoSize = .T.,;
BackStyle = 0,;
Caption = "需要準備",;
ForeColor = RGB(255,255,255),;
FontName = "細明體",;
FontSize = 12,;
Left = 15,;
Top = 52
ADD OBJECT txtTotal AS TEXTBOX WITH;
Enabled = .F.,;
FontName = "細明體",;
FontSize = 11,;
Height = 23,;
Left = 100,;
Top = 50,;
Width = 60
ADD OBJECT (SYS(2015)) AS LABEL WITH;
AutoSize = .T.,;
BackStyle = 0,;
Caption = "種車票",;
ForeColor = RGB(255,255,255),;
FontName = "細明體",;
FontSize = 12,;
Left = 165,;
Top = 52
ADD OBJECT lblRecL AS LABEL WITH;
AutoSize = .T.,;
BackStyle = 0,;
Caption = "計算中...",;
ForeColor = RGB(255,255,0),;
FontName = "細明體",;
FontSize = 10,;
Visible = .F.,;
Left = 15,;
Top = 75
ADD OBJECT lblRec AS LABEL WITH;
AutoSize = .T.,;
BackStyle = 0,;
Caption = "",;
ForeColor = RGB(255,255,0),;
FontName = "細明體",;
FontSize = 10,;
Visible = .F.,;
Left = 15,;
Top = 95
ADD OBJECT cmdYes AS CommandButton WITH;
Caption = "執行",;
Height = 25,;
Width = 75,;
Left = 15,;
Top = ThisForm.Height-36
ADD OBJECT cmdCancel AS CommandButton WITH;
Caption = "離開",;
Height = 25,;
Width = 75,;
Left = ThisForm.Width-90,;
Top = ThisForm.Height-36
PROCEDURE cmdYes.Click
* One
WITH This.Parent
STORE .spinNum.Value TO UserForm1_nNum
ENDWITH
UserForm1_nCircle = 2
* Two
* > 計算共有幾組以供顯示資訊使用
M_nReccount = 1
FOR UserForm1_SUB_A = UserForm1_nNum-UserForm1_nCircle+1 TO UserForm1_nNum
M_nReccount = M_nReccount * UserForm1_SUB_A
ENDFOR
FOR UserForm1_SUB_A = 1 TO UserForm1_nCircle
M_nReccount = M_nReccount / UserForm1_SUB_A
ENDFOR
* > 顯示記錄產生筆數資訊
WITH This.Parent
.lblRecL.Caption = "計算中... " + TRANSFORM(M_nReccount,M_nTran)
.lblRec.Caption = ""
.lblRecL.Visible = .T.
.lblRec.Visible = .T.
ENDWITH
__Esc = .F.
__IsCalc = .T.
UserForm1_nTotal = TT(UserForm1_nNum,UserForm1_nCircle)
__IsCalc = .F.
WITH This.Parent
.lblRec.Caption = PADR(.lblRec.Caption,LEN(M_nTran))
ENDWITH
WITH This.Parent
.txtTotal.Value = TRANSFORM(UserForm1_nTotal,"@R 99,999")
ENDWITH
WITH This.Parent
.lblRecL.Visible = .F.
.lblRec.Visible = .F.
ENDWITH
WAIT CLEAR
ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
DO CASE
* >> ESC
CASE nKeyCode = 27
__Esc = .T.
IF !__IsCalc
.cmdCancel.SetFocus
.cmdCancel.Click
ENDIF
ENDCASE
ENDPROC
PROCEDURE Destroy
ThisForm.Visible = .F.
RELEASE THISFORM
ENDPROC
PROCEDURE cmdCancel.Click
THISFORM.Destroy()
ENDPROC
ENDDEFINE
* ---------- ENDDEFINE CLASS ---------- *
FUNCTION TT
* ------------------------ *
* Input:
* L_nNum N 要幾個數字
* L_nCircle N 一次抽幾個
* Output:
* Lo_nTotal N 共有幾組
* ------------------------ *
PARAMETERS L_nNum,L_nCircle
LOCAL W1_SUB_A,W1_SUB_B
M_nMaxNum = L_nNum
M_nFiledCNT = L_nCircle
* 最後一筆的合計數:避免最後一筆會重覆一次
M_nSumOfLast = 0
FOR W1_SUB_A = M_nMaxNum-M_nFiledCNT+1 TO M_nMaxNum
M_nSumOfLast = M_nSumOfLast + W1_SUB_A
ENDFOR
* 建立暫存表格檔
W1_cCursorString = "CREATE CURSOR TMP_TT ("
FOR W1_SUB_A = 1 TO M_nFiledCNT
W1_cSUB_A = TRANSFORM(W1_SUB_A,"@L 999")
IF !W1_SUB_A = 1
W1_cCursorString = W1_cCursorString + ","
ENDIF
W1_cCursorString = W1_cCursorString + "N" + W1_cSUB_A + " N(3)"
ENDFOR
W1_cCursorString = W1_cCursorString + ")"
SELECT 0
&W1_cCursorString
* 取得排列組合的資料
=CIRCLE(1,L_nCircle,1)
* 顯示需要準備幾種車票(只有一半)
Lo_nTotal = RECCOUNT("TMP_TT")
* 關閉暫存表格檔
USE IN TMP_TT
RETURN Lo_nTotal * 2
FUNCTION CIRCLE
* 遞回函數
* ------------------------------------ *
* L_nMinNum N 最小數
* L_nChoice N 同一次還剩幾個數可以抽
* L_nWho N 每一次抽的第幾個數
* ------------------------------------ *
PARAMETERS L_nMinNum,L_nChoice,L_nWho
LOCAL W1_nMinNum,W1_nChoice,W1_nWho
LOCAL W1_SUB_A,W1_SUB_B,W1_nSumOfLast
LOCAL W1_nNextMinNum,W1_nNextChoice,W1_nNextWho
W1_nMinNum = L_nMinNum
W1_nChoice = L_nChoice
W1_nWho = L_nWho
* >
IF __Esc
RETURN
ENDIF
IF W1_nChoice = 0
RETURN
ENDIF
IF W1_nWho > M_nFiledCNT
RETURN
ENDIF
* >
IF W1_nWho = 1
SELECT TMP_TT
APPEND BLANK
WW_oMESSAGEBOX.lblRec.Caption = TRANSFORM(RECNO(),M_nTran) + ;
" (按 Esc 鍵中斷)"
ENDIF
* >
FOR W1_SUB_A = W1_nMinNum TO M_nMaxNum-W1_nChoice+1
REPLACE ("N"+TRANSFORM(W1_nWho,"@L 999")) WITH W1_SUB_A
* > 當每一筆的資料填滿時要新增下一筆
IF W1_nWho = M_nFiledCNT
* >> Set Filter:不是最後一筆
W1_nSumOfLast = 0
FOR W1_SUB_B = 1 TO M_nFiledCNT
W1_nSumOfLast = W1_nSumOfLast + EVAL("N"+TRANSFORM(W1_SUB_B,"@L 999"))
ENDFOR
IF W1_nSumOfLast = M_nSumOfLast
LOOP
ENDIF
* >> 新增
SELECT TMP_TT
SCATTER TO W1_aTT
APPEND BLANK
WW_oMESSAGEBOX.lblRec.Caption = TRANSFORM(RECNO(),M_nTran) + ;
" (按 Esc 鍵中斷)"
* >
IF RECNO() > 1 AND W1_nWho > 1
GATHER FROM W1_aTT
ENDIF
ENDIF
* >
IF !__Esc
__Esc = INKEY() = 27
ENDIF
IF __Esc
RETURN
ENDIF
W1_nNextMinNum = W1_SUB_A + 1
W1_nNextChoice = W1_nChoice - 1
W1_nNextWho = W1_nWho + 1
=CIRCLE(W1_nNextMinNum,W1_nNextChoice,W1_nNextWho)
IF __Esc
RETURN
ENDIF
ENDFOR
RETURN |
|
回頂端 |
|
![](templates/subSilver/images/spacer.gif) |
|
|
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
|
|