非重複隨機序列的高效生成(C語言)

非重複隨機序列的高效生成(C語言)

  • 問題描述
  • 思想+程序

閱讀之前注意:

本文閱讀建議用時:14min
本文閱讀結構如下表:

項目 下屬項目 測試用例數量
問題描述 0
思想+程序 1

問題描述

  1. 有一個長度爲N的序列,現在要你把它全部打亂順序,生成一個隨機的序列

思想+程序

思路1:

  1. 生成隨機數,要交換的序號=隨機數%長度
  2. 判斷要交換的序號是否已經被交換過,若交換過則跳回步驟1重新生成隨機數,若沒有交換過則交換後再跳回步驟1,直至所有的序號都被交換過

思路2:

  1. 第 i 次(i 從0開始且每次遞增1)生成隨機數,要交換的序號=隨機數%(長度- i )
  2. 交換序號 i 和 步驟1中“要交換的序號”,直至 i 遞增到了序列末尾

通常情況下我們會想到思路1,但當N非常大時,生成的隨機數%長度 得到的序號很有可能是已經交換過的序號,導致效率很低。
而思路2通過巧妙的固定規律交換,即序號 i 是有規律遞增的,而另一個要交換的序號是序列中序號 i 之後的任意一個隨機序號,同樣實現了隨機性,且保證了時間複雜度爲O(n),十分高效!
同樣是交換,祕訣在於交換的法則。

我們用C語言實現了思路2
程序參考以下代碼:

#include<stdio.h>
#include<stdlib.h>
#define N 10

void swap(int *a, int i, int j)
{
    int tmp = a[i];
    a[i] = a[j];
    a[j] = tmp;
}

void main()
{
    int i = 0;
    int a[N] = { 0 };
    for (i = 0; i < N; i++)
        a[i] = i + 1;
    for (i = 0; i < N; i++)//交換a[i]和a[i]後面的隨機序號
        swap(a, i, i + rand() % (N - i));
    for (i = 0; i < N; i++)
        printf("%d ", a[i]);
    system("pause");
}

可以看到代碼部分也十分簡潔1


  1. 問題源於一次面試,同時感謝前輩的點撥.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章