生成一个没有重复数字的随机数?

时间:2012-08-21 03:45:08

标签: c++ random

我想生成一个随机数,每个数字在0-9范围内,不重复自身。假设有限长度为4。

  • 1234符合条件,每个复合数字都是唯一的。
  • 1123不重复,1重复

请问这怎么办?

3 个答案:

答案 0 :(得分:6)

生成数字:

std::vector<int> vec = {0,1,2,3,4,5,6,7,8,9}; // or initialize from array if not c++11
std::random_shuffle(vec.begin(), vec.end());
vec.resize(4);

将数字加入一个数字:

int number = 0;
for (auto i = vec.begin(); i != vec.end(); ++i) {
    number = 10 * number + (*i);
}

答案 1 :(得分:0)

我相信你在谈论产生排列。

尝试这样的事情:

int used[10] = {0};
int n = 0;
int number = 0;

while( n < 10 ) {
    int d = rand() % 10;
    if( used[d] ) continue;
    used[d] = 1;
    number = number * 10 + d;
    n++;
}

不是最有效的...它只是跟踪已使用的数字,并在遇到使用过的数字时重新滚动。

上面确实有副作用,如果它是第一个选择的数字,技术上不使用零。您可以明确地阻止这种情况,或者只是接受一些数字长度为9位数。

答案 2 :(得分:0)

如果您宁愿避免不必要地使用std :: vector及其带来的内存分配,可能会在random_shuffle中使用过多的随机化调用,如果您使用某些数学运算,则会采用更简单的方法。

如果你可以计算存在多少有效(即可接受的)序列, C ,你可以设计一个从这个计数器映射到每个有效序列实例的双射函数,然后事情变得微不足道。生成[0, C ]范围内的随机整数,将其插入到函数中,返回有效输出。

如果我正确理解你的例子,你想要生成一个随机的4位数序列ABCD(表示[0,9999]范围内的整数),其中数字 A B C D 彼此不同。

有5040个这样的有效序列:10 * 9 * 8 * 7.

给定[0,5039]范围内的任何整数,以下函数将返回一个有效序列(即每个数字唯一的一个),表示为整数:

int counter2sequence(int u) {
  int m = u/504;
  u %= 504;
  int h = u/56;
  u %= 56;
  int t = u/7;
  u %= 7;

  const int ih = h;
  const int it = t;

  if (ih >= m) ++h;
  if (it >= ih) ++t;
  if (t >= m) ++t;
  if (u >= it) ++u;
  if (u >= ih) ++u;
  if (u >= m) ++u;

  return ((m*10 + h)*10 + t)*10 + u;
}

E.g。

counter2sequence(0) => 0123
counter2sequence(5039) => 9876