VFP 愛用者社區 首頁 VFP 愛用者社區
本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入

[原創]遞迴函數的應用範例2-排列

 
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區
上一篇主題 :: 下一篇主題  
發表人 內容
朱育興



註冊時間: 2003-08-25
文章: 661
來自: 台中市大里區

第 1 樓

發表發表於: 星期四 十月 16, 2003 3:47 pm    文章主題: [原創]遞迴函數的應用範例2-排列 引言回覆

* 前次發表「遞迴函數的應用範例」,那是關於數學的組合問題
* 這次是數學的排列問題
* 為了排列美觀的需求,空格是全形的空格,要引用程式碼時須
* 還原為半形的空格

* 遞迴函數的應用範例2-排列
* ---------------------------------------------------------- *
* 作者:朱育興 YSC 2003.10.16
* 1.這是在數學中的排列組合的題目
*  例:9 個數字排成一列的情形
* 2.目前限制 N 最大到 27,只是為了畫面顯示而設限的;事實上
*  N 是隨你設的,只要你的 CPU 耐操或 Cursor 沒爆掉的話。
* ---------------------------------------------------------- *

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 = 9
 .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    = 145
 Caption    = "N 個數字排成一列一覽表"

 ADD OBJECT (SYS(2015)) AS LABEL WITH;
  AutoSize   = .T.,;
  BackStyle   =  0,;
  Caption    = "請輸入 N 值",;
  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 = 27,;
  KeyboardLowValue =  1,;
  Left       = 130,;
  SpinnerHighValue = 27,;
  SpinnerLowValue  =  1,;
  Top        = 25,;
  Width       = 45

 ADD OBJECT lblRecL AS LABEL WITH;
  AutoSize   = .T.,;
  BackStyle   =  0,;
  Caption    = "記錄產生中...",;
  ForeColor   = RGB(255,255,0),;
  FontName   = "細明體",;
  FontSize   = 10,;
  Visible    = .F.,;
  Left     = 15,;
  Top      = 50

 ADD OBJECT lblRec AS LABEL WITH;
  AutoSize   = .T.,;
  BackStyle   =  0,;
  Caption    = "",;
  ForeColor   = RGB(255,255,0),;
  FontName   = "細明體",;
  FontSize   = 10,;
  Visible    = .F.,;
  Left     = 15,;
  Top      = 70

 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
 M_cThisCursorName = "TMP_9Group"
 * Two
 * > 計算共有幾組以供顯示資訊使用
 M_nReccount = 1
 FOR UserForm1_SUB_A = 1 TO UserForm1_nNum
  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.
 =CIRCLE(M_cThisCursorName,UserForm1_nNum)
 __IsCalc = .F.
 * > 顯示結果
 SELECT (M_cThisCursorName)
 GO TOP
 UserForm1_nWidth = ThisForm.Width
 UserForm1_nHeight = ThisForm.Height
 UserForm1_nTop  = ThisForm.Top
 UserForm1_nLeft  = ThisForm.Left
 ThisForm.Width  = 700
 ThisForm.Height  = 480
 ThisForm.Top   =  0
 ThisForm.Left   = 50
 BROWSE FIELDS GROUP:R:H="排列內容 " ;
     TITLE LTRIM(STR(UserForm1_nNum))+" 個數字排成一列一覽表"
 STORE UserForm1_nWidth TO ThisForm.Width
 STORE UserForm1_nHeight TO ThisForm.Height
 STORE UserForm1_nTop  TO ThisForm.Top
 STORE UserForm1_nLeft  TO ThisForm.Left
 * > 關閉由 CIRCLE 產生的暫存檔
 USE IN (M_cThisCursorName)
 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 CIRCLE
* 遞迴函數
* ------------------------------------------ *
* L_cCursorName C 存放排列的暫存表格檔之名稱
* L_nNum    N 從 1 排到幾
* ------------------------------------------ *
* 以下只供本函數內部使用
*
* L_nCircle   N 目前該組排列的第幾個
* L_cGroup   C 上層傳來的該組排列內容
* ------------------------------------------ *
LPARAMETERS L_cCursorName,L_nNum,L_nCircle,L_cGroup
LOCAL W1_SUB_A,W1_cSUB_A,W1_cGroup
IF __Esc
 RETURN
ENDIF

*
IF PCOUNT() = 2
 L_nCircle = 1
 L_cGroup = SPACE(0)
ENDIF

* 第一次執行本函數時:建立暫存表格檔(所有排列的情形)
IF L_nCircle = 1
 SELECT 0
 CREATE CURSOR (L_cCursorName) ;
  (GROUP C(80))
ENDIF

* 排列產生
FOR W1_SUB_A = 1 TO L_nNum
 W1_cSUB_A = TRANSFORM(W1_SUB_A,"@L 99")
 W1_cGroup = L_cGroup        && 承接上層傳來的排列內容
 IF W1_cSUB_A $ W1_cGroup      && 每一組排列不能有重覆的數字
  LOOP
 ENDIF
 IF !EMPTY(W1_cGroup)        && 加入新內容前的動作
  W1_cGroup = W1_cGroup + ","
 ENDIF
 W1_cGroup = W1_cGroup + W1_cSUB_A && 加入新內容
 IF L_nCircle = L_nNum       && 如果是最後一層就寫入 Cursor
  SELECT (L_cCursorName)
  APPEND BLANK
  REPLACE GROUP WITH W1_cGroup
  WW_oMESSAGEBOX.lblRec.Caption = TRANSFORM(RECNO(),M_nTran) + ;
                  " (按 Esc 鍵中斷)"
 ELSE                && 否則執行下一層遞迴函數
  IF !__Esc
   __Esc = INKEY() = 27
  ENDIF
  IF __Esc
   RETURN
  ENDIF
  =CIRCLE(L_cCursorName,L_nNum,L_nCircle+1,W1_cGroup)
 ENDIF
ENDFOR
RETURN
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 MSN Messenger
從之前的文章開始顯示:   
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區 所有的時間均為 台北時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
無法 在這個版面附加檔案
無法 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作