首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 從題庫隨機抽取考試試題的高效算法

     編輯:程式設計綜合問答

場景分析

  • 題庫量:< 1 萬題 → 全量載入內存,List<Question> 即可。
  • 題庫量:> 10 萬題 → 數據庫層面隨機,避免全表掃描。

方案對比

方案SQL/代碼優點缺點
內存 Fisher-Yates 洗牌 (小題庫)
var rnd = new Random();
var selected = questions
    .OrderBy(_ => rnd.Next()) // 簡單但 O(n log n)
    .Take(10)
    .ToList();
// 或標準洗牌 O(n)
for (int i = questions.Count - 1; i > 0; i--) {
    int j = rnd.Next(i + 1);
    (questions[i], questions[j]) = (questions[j], questions[i]);
}
return questions.Take(10);
極快、無數據庫壓力、支持複雜邏輯(去重、均衡知識點)題庫大時內存壓力
SQL TABLESAMPLE (PostgreSQL/SQL Server)
-- PostgreSQL
SELECT * FROM questions TABLESAMPLE SYSTEM (10) LIMIT 10;
-- SQL Server
SELECT TOP 10 * FROM questions TABLESAMPLE (10 PERCENT);
數據庫原生、無需全表排序非真隨機(頁級采樣)、小表不準
隨機 ID 範圍 + 索引查找 (大題庫通用)
-- 1. 獲取最大 ID
SELECT MAX(id) FROM questions; -- 假設 100000
-- 2. 應用層生成 10 個不重複隨機數 1~100000
-- 3. 批量查詢
SELECT * FROM questions WHERE id IN (?, ?, ...);
精確隨機、利用主鍵索引、極快ID 不連續時需調整(如 OFFSET 采樣)
ORDER BY RAND() (MySQL 小表)
SELECT * FROM questions ORDER BY RAND() LIMIT 10;
寫法最簡單全表掃描+臨時表排序,**大表極慢**

推薦:C# 內存洗牌 + 領域邏輯


public class ExamService {
    private readonly List _allQuestions; // 啟動時載入/緩存
    private readonly Random _rnd = new Random();

    public List GeneratePaper(int count, string[] categories = null) {
        IEnumerable pool = _allQuestions;
        if (categories != null) 
            pool = pool.Where(q => categories.Contains(q.Category));
        
        // Fisher-Yates 部分洗牌,只洗前 count 位
        var list = pool.ToList();
        int n = list.Count;
        for (int i = 0; i < count && i < n; i++) {
            int j = _rnd.Next(i, n);
            (list[i], list[j]) = (list[j], list[i]);
        }
        return list.Take(count).ToList();
    }
}

進階:知識點均衡

  • 按章節/難度分桶,各桶按比例抽取。
  • 用 GroupBy(q => q.Tag) 分組,組內洗牌取定額。

**題庫 ≤ 1 萬:全量載入內存 + Fisher-Yates 部分洗牌**,代碼最少、性能最強、業務邏輯最靈活。大題庫用「隨機 ID + 批量查詢」配合 Redis 緩存熱門題目。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved