#include <iostream>
#include <vector>
#include <string>
#include <random>
#include <algorithm>
#include <fstream>
int main() {
// 1. 使用 vector 動態儲存單詞
std::vector<std::string> words;
// 選項 A:程式碼中直接初始化(適合少量固定詞庫)
words = {"apple", "banana", "cherry", "date", "elderberry", "fig", "grape"};
// 選項 B:從檔案讀取(適合大量詞庫,每行一詞)
// std::ifstream fin("words.txt");
// std::string word;
// while (fin >> word) words.push_back(word);
if (words.empty()) {
std::cerr << "詞庫為空!\n";
return 1;
}
// 2. 建立高品質隨機數引擎(非 rand())
std::random_device rd; // 硬體熵源(非確定性)
std::mt19937 gen(rd()); // 梅森旋轉演算法(高品質、快速)
std::uniform_int_distribution<> dis(0, words.size() - 1); // 均勻分佈
// 3. 隨機抽取單一單詞
std::cout << "隨機單詞: " << words[dis(gen)] << '\n';
// 4. 進階:隨機抽取 N 個不重複單詞(洗牌演算法)
size_t n = 3;
std::vector<std::string> selected(words.begin(), words.end());
std::shuffle(selected.begin(), selected.end(), gen); // 原地隨機打亂
std::cout << "隨機抽取 " << n << " 個不重複單詞:\n";
for (size_t i = 0; i < n && i < selected.size(); ++i)
std::cout << " " << selected[i] << '\n';
// 5. 進階:加權隨機抽取(如單字難度權重)
// std::discrete_distribution<> weighted_dis({1, 2, 3, 1, 5, 1, 2});
// std::cout << "加權隨機: " << words[weighted_dis(gen)] << '\n';
return 0;
}
| 組件 | 作用 | 優於傳統寫法 |
|---|---|---|
std::vector<std::string> | 動態陣列,自動管理記憶體 | 避免緩衝區溢位、支援動態增刪、.size() O(1) |
std::random_device | 非確定性隨機種子(硬體熵源) | 避免 srand(time(0)) 秒級精度導致同秒啟動同序列 |
std::mt19937 | 梅森旋轉引擎(週期 2^19937-1) | 統計特性優、速度快、標準庫保證可移植 |
std::uniform_int_distribution | 將引擎輸出映射到指定整數範圍 | 無模數偏差、數學正確、型別安全 |
std::shuffle | Fisher-Yates 洗牌演算法 | O(N)、無偏、原地操作、標準庫實作 |
rand() % n模數偏差:RAND_MAX 通常為 32767,若 n 不整除 RAND_MAX+1,低數值機率略高。線性同餘引擎 統計特性差、週期短、執行緒不安全。
srand(time(0)) 在循環中重複呼叫同一秒內多次啟動會產生**相同隨機序列**。正確做法:程式啟動時**一次性**初始化引擎,全域/靜態儲存重複使用。
string words[100]若實際單詞 < 100,剩餘元素為空字串,隨機抽到空字串;若 > 100 發生緩衝區溢位。**永遠優先使用 std::vector**。
// C 風格:手動管理、易出錯
char *words[100];
int count = 0;
words[count++] = strdup("apple"); // 需手動 free
// 隨機:rand() % count // 有模數偏差
// 釋放:for(int i=0;i
std::unordered_map<std::string, std::vector<std::string>> 分類存儲。std::unordered_set 記錄已抽取單詞。thread_local std::mt19937 或 mutex 保護共享引擎。std::random_device 直接使用或 /dev/urandom / BCryptGenRandom。C++ 儲存單詞並隨機抽取,**標準配方**:std::vector<std::string> + std::mt19937 + std::uniform_int_distribution + std::shuffle。拒絕 rand()、srand(time(0))、固定陣列。標準庫提供數學正確、高效能、型別安全、可移植的完整解決方案,是現代 C++ 開發者的必備工具箱。