Generate a random number with no repeating digits?

匆匆过客 提交于 2020-01-04 10:11:10

问题


I'd like to generate a random number with each digit being in range from 0-9 and not repeating itself. Assume finite length of 4.

  • 1234 qualifies, each composite digit is unique.
  • 1123 does not, 1 is repeated

How can this be done please?


回答1:


To generate the digits:

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);

And to join the digits into a single number:

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



回答2:


I believe you are talking about generating permutations.

Try something like this:

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++;
}

Not the most efficient... It simply tracks what digits have been used, and rerolls any time a used digit is encountered.

The above does have the side-effect that zero is technically not used if it's the first number chosen. You could explicitly prevent this, or simply accept that some numbers will be 9 digits long.




回答3:


If you'd rather avoid needless use of std::vector and the memory allocations it brings, excessive randomisation calls presumably used within random_shuffle, there's a simpler approach if you play with some math.

If you can count how many valid (i.e. acceptable) sequences exist, C, and you can devise a bijective function that maps from this counter to each valid sequence instance then things become trivial. Generate a random integer in the range [0,C), plug that into your function which returns the valid output.

If I understand your example correctly, you want to generate a random 4 digit sequence ABCD (representing an integer in the range [0,9999]) where digits A, B, C and D are different from one another.

There are 5040 such valid sequences: 10 * 9 * 8 * 7.

Given any integer in the range [0, 5039], the following function will return a valid sequence (i.e. one in which each digit is unique), represented as an integer:

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


来源:https://stackoverflow.com/questions/12048175/generate-a-random-number-with-no-repeating-digits

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!