範圍內的隨機唯一數生成演算法

更新於 發佈於 閱讀時間約 3 分鐘

今天如果要你印出1-100之間的不重複隨機數排列,你該怎麼做?

我們直接來看程式碼:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#define N 100 // 定義陣列的大小為100

int main() {
int i, r, sum = 0;
bool occupied[N] = {0}; // 初始化一個大小為N的陣列,用來追蹤哪些位置已被佔據
time_t t;
unsigned int count = 0; // 用來計數的變數

// 初始化隨機數生成器
srand((unsigned)time(&t));

// 遍歷陣列並輸出當前occupied陣列的值
for (i = 0; i < N; i++) {
printf("%2d %d ", i, occupied[i]);

// 每10個輸出一行
if ((i + 1) % 10 == 0) {
printf("\n");
}
}

printf("\n");

// 開始隨機分配occupied陣列的元素
for (i = 0; i < N; i++) {
count++; // 增加計數器
r = rand() % N; // 隨機生成一個0到N-1的數字

// 如果當前的元素尚未被佔據
if (!occupied[r]) {
printf("%3d ", r + 1); // 打印隨機選中的數字,+1使其從1開始
occupied[r] = 1; // 將該位置標記為已佔據

// 每10個數字輸出一行
if ((i + 1) % 10 == 0) {
printf("\n");
}
} else {
i--; // 如果隨機生成的位置已經被佔據,重新嘗試
}
}

// 輸出count結果,顯示總共進行了多少次隨機選取(包括重試次數)
printf("\nTotal random selections: %d\n", count);

return 0;
}
  • 這段程式碼的核心目的是 生成一組 1 到 100 的不重複隨機數排列,確保每個數字只出現一次,並且隨機順序排列。
  • 建立一個大小為 100 (N=100) 的布林陣列 occupied[]
    • occupied[i] = 0 表示這個數字尚未被選中。
    • occupied[i] = 1 表示這個數字已被選中,不可以重複選取。

if (!occupied[r]) {  // 如果這個索引還沒有被選取
printf("%3d ", r + 1); // 輸出 (轉換為 1~100)
occupied[r] = 1; // 標記為已選取
  • r + 1 讓輸出變成 1~100 而不是 0~99
  • occupied[r] = 1 確保這個數字不會被重複選取。

} else {
i--; // 這次選取無效,i 不增加
}

r 這個數字已經被選取過時:

  • i--i 不增加,表示這次隨機選取無效,必須重新選取新的數字,這樣就確保了每個數字只會出現一次
  • 如果不 i--,則會少輸出一個數字。
在當今數位時代,電資領域人才需求爆發式成長,不論是前端網頁設計、嵌入式開發、人工智慧、物聯網還是軟硬體整合,這些技術都在改變世界。而掌握 C/C++、Python、數位邏輯、電路學與嵌入式開發等大學電資領域的課程,正是進入這個高薪、高需求產業的關鍵!
留言
avatar-img
留言分享你的想法!
遞迴就是函式在執行過程中呼叫自身,並通過結束條件和呼叫堆疊來解決問題。 這種方式通常用於解決可以分解為相同問題的子問題的情況。 本章節將以最容易理解的方式解說這個核心概念,並且邁入較艱深的應用範例,提升程式思考邏輯力。
內插搜尋法(Interpolation Search)是一種改進版的 二分搜尋法,但它不是直接取中間值,而是 根據目標值的位置,預測索引的範圍,類似於人類在 查找電話簿 或 字典 時的方式。 本章節將帶你了解此演算法概念,並透過C語言實作。
二分搜尋法(Binary Search)是一種 高效的搜尋演算法,適用於 已排序 的資料結構。 它的核心思想是 每次將搜尋範圍減半,直到找到目標值或範圍縮小到無法繼續搜尋。 本章節將帶領讀者學會這個演算法,並透過C語言實作。
循序搜尋法(Sequential Search)是一種最簡單的搜尋演算法,適用於線性結構。 它的基本概念是 逐一檢查每個元素,直到找到目標值或遍歷完整個結構。 本章節將會帶領讀者熟悉這個知識,並且用C語言實作。
歸併排序法 同樣是一種基於「分治法」(Divide and Conquer)的排序演算法,我們將逐步分析演算法的思維與流程,最後以程式碼實作出來。
本章節以清楚易懂的圖示呈現快速排序法的思維,並演示了如何用程式碼實作。
遞迴就是函式在執行過程中呼叫自身,並通過結束條件和呼叫堆疊來解決問題。 這種方式通常用於解決可以分解為相同問題的子問題的情況。 本章節將以最容易理解的方式解說這個核心概念,並且邁入較艱深的應用範例,提升程式思考邏輯力。
內插搜尋法(Interpolation Search)是一種改進版的 二分搜尋法,但它不是直接取中間值,而是 根據目標值的位置,預測索引的範圍,類似於人類在 查找電話簿 或 字典 時的方式。 本章節將帶你了解此演算法概念,並透過C語言實作。
二分搜尋法(Binary Search)是一種 高效的搜尋演算法,適用於 已排序 的資料結構。 它的核心思想是 每次將搜尋範圍減半,直到找到目標值或範圍縮小到無法繼續搜尋。 本章節將帶領讀者學會這個演算法,並透過C語言實作。
循序搜尋法(Sequential Search)是一種最簡單的搜尋演算法,適用於線性結構。 它的基本概念是 逐一檢查每個元素,直到找到目標值或遍歷完整個結構。 本章節將會帶領讀者熟悉這個知識,並且用C語言實作。
歸併排序法 同樣是一種基於「分治法」(Divide and Conquer)的排序演算法,我們將逐步分析演算法的思維與流程,最後以程式碼實作出來。
本章節以清楚易懂的圖示呈現快速排序法的思維,並演示了如何用程式碼實作。
你可能也想看
Google News 追蹤
Thumbnail
全方位分析脫離繼承戰的方法,大膽猜測誰會成為卡丁國下一任國王。
Thumbnail
全方位分析脫離繼承戰的方法,大膽猜測誰會成為卡丁國下一任國王。