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

C語言生成指定範圍隨機數並查找目標值:完整實現與統計分析

     編輯:C 語言問答

題目需求

生成 10 個 50-60 之間的隨機整數,判斷是否包含 55。

標準實現

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    int a[10];
    int i, found = 0;
    
    // 1. 設置種子 (僅一次!)
    srand((unsigned int)time(NULL));
    
    // 2. 生成 10 個 [50, 60] 範圍隨機數
    printf("生成的隨機數: ");
    for (i = 0; i < 10; i++) {
        // rand() % 11 生成 0-10,+50 得到 50-60
        a[i] = 50 + rand() % 11;
        printf("%d ", a[i]);
        
        // 3. 同時檢查是否為 55
        if (a[i] == 55) found = 1;
    }
    printf("\n");
    
    // 4. 輸出結果
    if (found) {
        printf("找到 55!\n");
    } else {
        printf("未找到 55。\n");
    }
    
    // 5. 統計分析 (額外)
    int count[11] = {0};  // 50-60 對應索引 0-10
    for (i = 0; i < 10; i++) count[a[i] - 50]++;
    
    printf("\n頻率統計:\n");
    for (i = 0; i < 11; i++) {
        if (count[i] > 0) {
            printf("%d: %d 次\n", 50 + i, count[i]);
        }
    }
    
    return 0;
}

關鍵知識點

範圍映射公式

// 生成 [min, max] 之間的隨機整數 (包含邊界)
int rand_range(int min, int max) {
    return min + rand() % (max - min + 1);
}

// 通用宏
#define RAND_RANGE(min, max) ((min) + rand() % ((max) - (min) + 1))

為什麼要 srand(time(NULL))?

  • rand() 產生確定性偽隨機序列
  • 默認種子為 1 → 每次運行結果相同
  • time(NULL) 返回當前秒數,每次運行種子不同
  • 全程序只調用一次,不要在循環中調用

rand() 偏差問題 (模數偏差)

當 RAND_MAX 不是範圍大小的整數倍時,rand() % N 會導致分布不均。

// 改進版:拒絕採樣消除偏差
int rand_range_unbiased(int min, int max) {
    int range = max - min + 1;
    int buckets = RAND_MAX / range;
    int limit = buckets * range;
    int r;
    do {
        r = rand();
    } while (r >= limit);
    return min + r / buckets;
}

進階:統計驗證隨機性

#include <math.h>

void chi_square_test(int *freq, int n, int range) {
    double expected = (double)n / range;
    double chi2 = 0;
    for (int i = 0; i < range; i++) {
        double diff = freq[i] - expected;
        chi2 += diff * diff / expected;
    }
    printf("卡方統計量: %.3f (自由度 %d)\n", chi2, range - 1);
    // 查表判斷是否拒絕"均勻分布"假設
}

現代 C (C11) 更好的隨機數

C11 引入 <stdalign.h> 但隨機數仍舊用 rand/srand。真正現代化需 C++ <random> 或第三方庫。

常見錯誤

錯誤代碼問題修正
rand() % 10 + 50生成 50-59,漏掉 60rand() % 11 + 50
循環中 srand(time(NULL))同一秒內種子相同,生成相同數列程序啟動時調用一次
未包含 <stdlib.h>隱式聲明警告添加頭文件
a[i] = rand() * 10 / RAND_MAX + 50浮點運算慢且有精度問題整數取模更快

擴展練習

  1. 生成 1000 個數,驗證分布均勻性 (卡方檢定)
  2. 實現「不重複」隨機數生成 (洗牌算法 / 集合去重)
  3. 將結果寫入文件,用 Python/Excel 繪製直方圖
  4. 對比 rand()、random() (BSD)、arc4random() (BSD/macOS) 質量
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved