当我们无法存储以前生成的random时,生成唯一的randoms

时间:2017-03-25 17:17:06

标签: c# arrays math random

我们有一个数组(例如字符串)。此数组的大小不固定。

现在,我们的机器每隔3分钟选择一个该阵列的元素并向我们展示。问题是我们没有内存来存储我们之前选择的元素,当我们从这个数组中选择时,我们希望元素首先覆盖整个数组,然后它们可以自由重复,但是在每个元素被拾取一次之前,它们不应该重复。

我们没有内存来存储拾取的元素,但是我们可以获得MinutesInDay变量(当天已经过了多少分钟)。我相信使用这个变量可以完成一些事情。

1 个答案:

答案 0 :(得分:0)

一种解决方案是保持包含随机选择的字符串的数组(或指向所选字符串的指针),并在选择时从可用字符串数组中删除字符串。这样,存储的字符串数量总是只比您开始使用的字符串数量大一个;一个更大,因为在每次迭代中,所选字符串在从chosen数组中删除之前被复制到available数组中。当available数组为空时,chosen的内容可以复制回available,并且循环可以重复。

OP没有指定语言,但这里是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;
}