我們有一個數組(例如字符串)。這個數組的大小不固定。當我們無法存儲先前生成的隨機數時,生成獨特的隨機數
現在,我們的機器每隔3分鐘選擇一個這個數組的元素並顯示給我們。問題是我們沒有內存來存儲我們之前選擇的元素,每隔3分鐘我們就會選擇這個數組,我們希望這些元素首先覆蓋整個數組,然後可以自由地重複,但是在每個元素被拾取一次之前,他們不應該重複。
我們沒有內存來存儲拾取的元素,但我們可以得到MinutesInDay變量(當天有多少分鐘已經過去)。我相信可以用這個變量來完成一些事情。
我們有一個數組(例如字符串)。這個數組的大小不固定。當我們無法存儲先前生成的隨機數時,生成獨特的隨機數
現在,我們的機器每隔3分鐘選擇一個這個數組的元素並顯示給我們。問題是我們沒有內存來存儲我們之前選擇的元素,每隔3分鐘我們就會選擇這個數組,我們希望這些元素首先覆蓋整個數組,然後可以自由地重複,但是在每個元素被拾取一次之前,他們不應該重複。
我們沒有內存來存儲拾取的元素,但我們可以得到MinutesInDay變量(當天有多少分鐘已經過去)。我相信可以用這個變量來完成一些事情。
一種解決方案是保持一個包含隨機選擇的字符串(或指向所選字符串的指針)的數組,並從可用字符串數組中選擇字符串時刪除字符串。通過這種方式,存儲的字符串數量總是隻會比您開始使用的字符串數量大一個;一個更大,因爲在每次迭代中,所選的字符串在從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;
}
@ Sanjay--我在評論中看到你提到過C#。我不使用C#,但我在答案中添加了C版本的代碼,可能更接近您要查找的內容。 –
語言?是否必須隨機選擇元素,還是順序確定?我還沒有完全想到它,但我懷疑這可以通過反應式編程和觀測器相當容易地完成,特別是如果順序訪問正常。 –
我假定有一些僞隨機性的要求,因爲你使用的是隨機標籤。否則,只顯示第一個元素,然後顯示第二個元素等等。序列需要多少隨機數?沒有明顯的模式給一個隨便的觀察者?還是比這更強大的東西? –
在此過程中數組是否更改大小?如果沒有,您可以隨機洗牌,然後選擇新訂單中的商品。到達最後時,再次洗牌並再次從頭開始顯示。或者,您可以只存儲一個顯示爲'1'的位數組,'0'還未顯示。與字符串相比,這將花費很少的內存。 –