用于在数组中存储唯一随机数的伪代码

时间:2014-04-23 19:49:43

标签: arrays random unique pseudocode

好吧,伙计们,我显然是个白痴,无法弄清楚这个简单的问题。

我的其余代码并不值得,所以我只是发布相关代码。我已经知道为什么它被打破了,但我不知道怎么解决它。我真的只是寻找伪代码给我一个起点。

我尝试做的是创建一个名为" temp"的数组,并在其5个索引中的每个索引中存储一个唯一的随机数(这些数字稍后将用作不同的索引)数组)。它不仅仅是将其从1初始化为5并使用随机播放的问题,因为随机数可以达到我的图中的顶点数量numVertices。

int place = -1;

int temp[5] = {-1};
for(int i = 0; i < 5 || i < numVertices; i++){
    do{
        place = rand();
        place = (double)place / RAND_MAX * numVertices;
        temp[i] = place;
    } while(place == temp[0] or
          place == temp[1] or
          place == temp[2] or
          place == temp[3] or 
          place == temp[4]); ......`

显然,我的代码卡在无限循环中,因为它将地点(随机索引I&m; m存储到不同的数组中)与temp [i]进行比较,并且在执行操作后它将始终等于temp [一世]。我要做的就是将它与其他人进行比较,然后去&#34;如果它与已存储的数字之一匹配,则再次随机放置,直到它不匹配,然后将其存储在下一个插槽中在温度&#34;但是,我不能想到如何做到这一点。

4 个答案:

答案 0 :(得分:2)

如果你将事情分解成简单的部分,这会有所帮助。看起来你在这里使用的是C语言。所以,首先定义顶点数量:

#define NUM_VERTICES 1000

然后是一个简单的函数来生成随机数x,使得lower_bound&lt; = x&lt; UPPER_BOUND:

int next_random( int inclusive_lower_bound , int exclusive_upper_bound )
{
  int n = exclusive_upper_bound - inclusive_lower_bound ; // size of desired domain
  int r = rand() % n ;                                    // 0 <= r < n
  int x = inclusive_lower_bound + r ;                     // min <= x < max
  return x ;
}

然后是一个简单的函数来查看你的缓冲区是否已经包含一个值:

int contains( int x, int *p, int limit)
{
  int j = 0 ;
  while ( j < limit && p[j] != x )
  {
    ++j;
  }
  return (j < limit ? 1 : 0);
}

然后是一个简单的函数来生成域中的下一个唯一值:

int next_unique_random( int* p, int limit, int upper_bound )
{
  int x , j ;
  do
  {
    x = next_random( 0 , upper_bound ) ;
  } while ( contains(x,p,limit) ) ;
  return x ;
}

最后,我们可以把它们放在一起:

int main()
{
  int temp[5] = { 0, 0, 0, 0 } ;
  int i = 0;

  for (i = 0; i < 5; ++i )
  {
    temp[i] = next_unique_random( temp , i , NUM_VERTICES ) ;
  }

  return 0;
}

容易!

答案 1 :(得分:0)

而不是写一个巨大的条件,写另一个循环。

...
while (true) {
    ...
    bool tryAgain = false;
    for(int j = 0; j < i; j++) {
        if (temp[j] == temp[i]) 
            tryAgain = true;
    }
    if (!tryAgain)
         break;
}

但如果我用Java写这个,我会使用HashSet来存储数字并使用其有效的contains方法来告诉我我是否已经使用过这个数字。虽然,因为数组太小(5个元素),所以无论如何,上面的代码应该非常快。

答案 2 :(得分:0)

#include <array>
#include <cstdlib>
#include <ctime>
#include <set>
#include <iostream>

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

  std::array<int, 5> a;
  std::set<int> s;
  int r;

  for(size_t i = 0; i < a.size(); ++i)
  {
    do 
    {
      r = rand();
    } while(s.find(r) != s.end());

    a[i] = r;
    s.insert(r);
  }

  for(const auto& i: a)
    std::cout << i << std::endl;

  return 0;
}

答案 3 :(得分:0)

再次编辑:我刚看到你的评论:

'use strict'

var numVertices = 100,
    temp = [];

var RAND_MAX = 32767;

for(var i = 0; i < 5; i++){
    var place = parseInt(Math.random() * numVertices),  // C++ : rand() % numVertices
        valid = true;
    //place = place * numVertices;
    for(var x = 0; x < temp.length; x++) {
        if(temp[x] == place) {
            i--;
            valid = false;
            break
        }
    }
    if(valid) temp[i] = place;
}
console.log(temp);

在比较浮点数/双打时,你不能使用==,这是在Javascript中执行此操作的代码,但它很容易移植:

*编辑:*检查What is the most effective way for float and double comparison?以获取有关比较浮点数的更多信息。

'use strict'

var numVertices = 5,
    temp = [];

var RAND_MAX = 32767,
    EPSILON = 1.00000001

for(var i = 0; i < 5 || i < numVertices; i++){
    var place = Math.random(),
        valid = true;
    place = place / RAND_MAX * numVertices;
    for(var x = 0; x < temp.length; x++) {
        if(Math.abs(temp[x] - place) > EPSILON) { //Math.abs == fabs in C/C++
            i--;
            valid = false;
            break
        }
    }
    if(valid) temp[i] = place;
}
console.log(temp);