首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

可自訂範圍與數量的不重複隨機數生成函數實作

     編輯:關於VC++

需求背景

考試軟體需求:每次出題順序不同、題目數量可配置、且不可重複。C++ 標準庫 rand() 無現成支援,故封裝通用擴展函數 randEx(int MAX, int NUM)。

演算法邏輯

  1. 以 time(&t) 設定隨機種子,確保每次序列不同
  2. 外層迴圈產生 NUM 個隨機數
  3. 內層 do-while 檢查新數是否與已產生數重複
  4. 重複則重新產生,直到不重複為止
  5. 結果存於全域陣列 RAND[] (1-based 索引)

完整代碼實作

void randEx(int MAX, int NUM) {
    int k = 0, j = 0;
    time_t t;
    srand((unsigned)time(&t));          // 設定種子
    for (k = 1; k <= NUM; k++) {        // 1-based 索引
        RAND[k] = rand() % MAX;         // 0 ~ MAX-1
        do {
            for (j = 1; j < k; j++) {
                if (RAND[j] == RAND[k]) { // 發現重複
                    RAND[k] = rand() % MAX;
                    break;              // 跳出內層 for,do-while 繼續檢查
                }
            }
        } while (j < k);                // 若 j==k 表示無重複,結束 do-while
    }
}

使用範例:對話框顯示前 10 個隨機數

標頭檔宣告

class CTestRandDlg : public CDialog {
public:
    int RAND[20];                       // 足夠容納最大需求
    void randEx(int MAX, int NUM);
    CWnd* p_StaticWnd;
    // ...
};

按鈕事件處理

void CTestRandDlg::OnTestrand() {
    UpdateData(TRUE);
    randEx(m_nRandMax, m_nRandNum);     // 使用者輸入最大值與數量

    CString str;
    for (int i = 1; i <= m_nRandNum && i <= 10; i++) {
        str.Format(_T("%d"), RAND[i]);
        p_StaticWnd = GetDlgItem(IDC_STATIC1 + i - 1);
        p_StaticWnd->SetWindowText(str);
    }
    UpdateData(FALSE);
}

測試環境:VC++ 6.0 + Windows XP,編譯通過。

效能與改進建議

  • 時間複雜度:O(NUM²) 適合小規模 (NUM < 1000),大規模建議改用 Fisher-Yates Shuffle (洗牌演算法) O(N)
  • 隨機品質:rand() 週期短,關鍵應用建議用 std::mt19937 (C++11) 或 CryptGenRandom
  • 執行緒安全:全域陣列與 srand/rand 非執行緒安全,多執行緒需加鎖或改用 thread_local 引擎
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved