  | 
				VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.   
				 | 
			 
		 
		 
	
		| 上一篇主題 :: 下一篇主題   | 
	 
	
	
		| 發表人 | 
		內容 | 
	 
	
		朱育興
 
 
  註冊時間: 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 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
  	 
	    
  	   | 
 	
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
  | 
   
  
		 |