2017-03-25 88 views
-3

我們有一個數組(例如字符串)。這個數組的大小不固定。當我們無法存儲先前生成的隨機數時,生成獨特的隨機數

現在,我們的機器每隔3分鐘選擇一個這個數組的元素並顯示給我們。問題是我們沒有內存來存儲我們之前選擇的元素,每隔3分鐘我們就會選擇這個數組,我們希望這些元素首先覆蓋整個數組,然後可以自由地重複,但是在每個元素被拾取一次之前,他們不應該重複。

我們沒有內存來存儲拾取的元素,但我們可以得到MinutesInDay變量(當天有多少分鐘已經過去)。我相信可以用這個變量來完成一些事情。

+1

語言?是否必須隨機選擇元素,還是順序確定?我還沒有完全想到它,但我懷疑這可以通過反應式編程和觀測器相當容易地完成,特別是如果順序訪問正常。 –

+0

我假定有一些僞隨機性的要求,因爲你使用的是隨機標籤。否則,只顯示第一個元素,然後顯示第二個元素等等。序列需要多少隨機數?沒有明顯的模式給一個隨便的觀察者?還是比這更強大的東西? –

+1

在此過程中數組是否更改大小?如果沒有,您可以隨機洗牌,然後選擇新訂單中的商品。到達最後時,再次洗牌並再次從頭開始顯示。或者,您可以只存儲一個顯示爲'1'的位數組,'0'還未顯示。與字符串相比,這將花費很少的內存。 –

回答

0

一種解決方案是保持一個包含隨機選擇的字符串(或指向所選字符串的指針)的數組,並從可用字符串數組中選擇字符串時刪除字符串。通過這種方式,存儲的字符串數量總是隻會比您開始使用的字符串數量大一個;一個更大,因爲在每次迭代中,所選的字符串在從available陣列中移除之前被複制到chosen陣列中。當available數組爲空時,chosen的內容可以被複制回available,並且循環可以重複。

的任擇議定書沒有指定語言,但這裏是Lua的腳本作爲一個概念證明:

math.randomseed(os.time()) 

available = { "String 1", "String 2", "String 3", "String 4", "String 5" } 
chosen = {} 

for count = 1, 3 * #available do 

    -- Choose random member from available 
    local i = math.random(1, #available) 
    print(available[i]) 

    -- Add member to chosen 
    table.insert(chosen, available[i]) 

    -- Remove from available 
    table.remove(available, i) 

    -- Reset and repeat 
    if #available == 0 then 
     available = chosen 
     chosen = {} 
     print() 
    end 
end 

下面是幾個樣品運行的輸出:

> dofile("unique_randoms_43019470.lua") 
String 5 
String 3 
String 2 
String 1 
String 4 

String 4 
String 3 
String 5 
String 2 
String 1 

String 5 
String 1 
String 4 
String 3 
String 2 

> dofile("unique_randoms_43019470.lua") 
String 1 
String 4 
String 2 
String 3 
String 5 

String 1 
String 2 
String 3 
String 5 
String 4 

String 4 
String 1 
String 5 
String 2 
String 3 

這裏一個適用於數組的C版本,可以輕鬆擴展到動態分配的數組。此代碼將刪除available的隨機成員,並將其移到數組中,使其超過剩餘的可用字符串,從而縮小可用池的大小。輸出可與Lua版本相媲美:

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

#define START_SIZE 5 

void remove_available(size_t ndx, char **list, size_t list_sz); 

int main(void) 
{ 
    srand((unsigned) time(NULL)); 

    size_t available_sz = START_SIZE; 
    char *available[START_SIZE]; 

    available[0] = "String 1"; 
    available[1] = "String 2"; 
    available[2] = "String 3"; 
    available[3] = "String 4"; 
    available[4] = "String 5"; 

    for (size_t count = 0; count < 3*START_SIZE; count++) { 

     /* Choose random member from available */ 
     size_t i = rand() % available_sz; 
     puts(available[i]); 

     remove_available(i, available, available_sz); 
     --available_sz; 

     /* Reset and repeat */ 
     if (available_sz == 0) { 
      available_sz = START_SIZE; 
      putchar('\n'); 
     } 
    } 

    return 0; 
} 

/* Remove element at ndx and move to end of available segment */ 
void remove_available(size_t ndx, char **av, size_t av_sz) 
{ 
    --av_sz; 
    char *temp = av[ndx]; 

    for (size_t i = ndx; i < av_sz; i++) { 
     av[i] = av[i+1]; 
    } 
    av[av_sz] = temp; 
} 
+0

@ Sanjay--我在評論中看到你提到過C#。我不使用C#,但我在答案中添加了C版本的代碼,可能更接近您要查找的內容。 –