By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,441 Members | 979 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,441 IT Pros & Developers. It's quick & easy.

How to create a random number x times and only show it once

P: n/a
I have the random number generator that works but the some numbers repeat. I want to create 26 numbers between 1 and 26 and each number can only be used once.

Expand|Select|Wrap|Line Numbers
  1.     srand((unsigned)time(0)); 
  2.     int randNum=1; 
  3.     for(int amtNum=0; amtNum<26; amtNum++)
  4.     { 
  5.  
  6.     randNum = (rand()%26)+1;  // makes random number from 1 to 26
  7.  
  8.     cout << randNum << endl;
  9.  
Oct 9 '10 #1
Share this Question
Share on Google+
3 Replies


Expert 100+
P: 2,398
Perhaps the simplest approach is to keep track of the numbers you already have. Each time you get a new random number check to see if it is one you already have. If it is, then discard it and loop back and try again.

Somewhat more complicated would be to start with a pool of 26 numbers. Pick a 1-in-26 random value and use it as an index into the pool. You now are left with a pool of 25 values. Pick a 1-in-25 random value. Repeat until you're done. No need to do a final pick when the pool has only one value in it.

This more complicated approach will complete in precisely 26 equal-size steps. The simpler approach will take progressively longer -- you will find yourself spending more and more time discarding repeated values.
Oct 9 '10 #2

ADezii
Expert 5K+
P: 8,628
I'm on the other side of town in the Access Forum, and I accidentally came across this Thread. I created an Algorithm many years ago in Visual Basic that will accomplish exactly what you are requesting. It is portable, and should easily be converted to any language (C in this case). The General Logic is as follows:
  1. Generate a Random Number of Values as defined by the CONSTANT conNUM_OF_VALUES (in your case, 26).
  2. Populate an Array with these Randomly Generated Values between 1 and conNUM_OF_VALUES.
  3. Iterate through this Array via 2 Nested Loops checking every Value in the Array against itself, except for equivalent Indexes.
  4. Repeat this process as long as Duplicate(s) exist.
  5. Output the results to the Immediate Window.
  6. I normally do not like the idea of using Unconditional Branching with GoTo outside of Error Trapping, but it seems to work well in this case. This Logic can easily be replace with a variation of the Do...Loop Structure using a Boolean Variable to check for Duplication.
  7. The Logic seems to work quite well with a small number of Randoms, but has never been tested with a larger amount.
    Expand|Select|Wrap|Line Numbers
    1. 'Array to hold Randomly Generated Numbers
    2. Dim aintRndNums() As Integer
    3. Const conNUM_OF_VALUES As Integer = 26      'Assume Ranges starts at 1 (1 to 26)
    4. ReDim aintRndNums(1 To conNUM_OF_VALUES)    'Redimension appropriately
    5. Dim intCtr As Integer                       'Counter for Loops
    6. Dim intCtr_2 As Integer                     'Counter for Loops
    7.  
    8. Randomize   'Seed the Random Number Generator
    9.  
    10. 'Poppulate Array with conNUM_OF_VALUES Randomly Generated Numbers
    11. 'between 1 and conNUM_OF_VALUES
    12. For intCtr = 1 To conNUM_OF_VALUES
    13.   aintRndNums(intCtr) = Int(Rnd() * conNUM_OF_VALUES + 1)
    14. Next intCtr
    15.  
    16. 'Lets eliminate the Duplicates
    17. DoItAllOverAgain:
    18. For intCtr = 1 To UBound(aintRndNums)
    19.   For intCtr_2 = 1 To UBound(aintRndNums)
    20.     If intCtr <> intCtr_2 Then      'Check each Element against every other
    21.                                     'Element except itself for Dups
    22.       If aintRndNums(intCtr) = aintRndNums(intCtr_2) Then    'a Dup, get a New Random
    23.         aintRndNums(intCtr) = Int(Rnd() * conNUM_OF_VALUES + 1)
    24.           GoTo DoItAllOverAgain
    25.       End If
    26.     End If
    27.   Next intCtr_2
    28. Next intCtr
    29.  
    30. 'For Verification purposes
    31. For intCtr = 1 To conNUM_OF_VALUES
    32.   Debug.Print aintRndNums(intCtr)
    33. Next intCtr
  8. OUTPUT:
    Expand|Select|Wrap|Line Numbers
    1.  10 
    2.  23 
    3.  1 
    4.  4 
    5.  20 
    6.  25 
    7.  15 
    8.  22 
    9.  18 
    10.  14 
    11.  8 
    12.  9 
    13.  21 
    14.  11 
    15.  5 
    16.  12 
    17.  19 
    18.  17 
    19.  2 
    20.  24 
    21.  26 
    22.  7 
    23.  13 
    24.  6 
    25.  16 
    26.  3 
Oct 9 '10 #3

P: 2
Well, what i did was to create a bool array and check every time if number was used in a while statement.
Check bellow.
____________________________________________

Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <time.h>
  3.  
  4. using namespace std;
  5.  
  6. const int MAX_NUM(26);
  7.  
  8. class RANDOM_NUM{
  9. public:
  10.     void CreateRandNum();
  11.     void SetNumsUnused();
  12.     bool CheckIfAllUsed();
  13.     int GetRandNum();
  14. private:
  15.     bool numberUsed[MAX_NUM];
  16.     int randNum;
  17. };
  18.  
  19. void RANDOM_NUM::CreateRandNum()
  20. {
  21.         bool numIsUsed(true); 
  22.  
  23.         do{
  24.             randNum = (rand()%26)+1; 
  25.             if(!numberUsed[randNum-1]) // if number is not used exit statement  and set it to used.
  26.             {
  27.                 numberUsed[randNum-1] = true;
  28.                 numIsUsed=false;
  29.             }
  30.  
  31.         }while(numIsUsed);
  32. }
  33.  
  34. bool RANDOM_NUM::CheckIfAllUsed()
  35. {
  36.         for(int i=0;i<MAX_NUM;i++)
  37.         {
  38.             if(!numberUsed[i]) // if a number is not used it returns false.
  39.                 return false;
  40.  
  41.         }
  42.  
  43.         return true;
  44. }
  45.  
  46. void RANDOM_NUM::SetNumsUnused()
  47. {
  48.     for(int i=0;i<MAX_NUM;i++)
  49.         numberUsed[i] = false;
  50. }
  51.  
  52. int RANDOM_NUM::GetRandNum()
  53. {
  54.     return randNum;
  55. }
  56.  
  57. int main(int argc,char *argv)
  58. {
  59.      srand((unsigned)time(0)); 
  60.     RANDOM_NUM randomNum;
  61.     randomNum.SetNumsUnused();
  62.  
  63.     while(!randomNum.CheckIfAllUsed())
  64.     {
  65.         randomNum.CreateRandNum();
  66.         cout << "Random Number: " << randomNum.GetRandNum() << endl;
  67.     }
  68.     getchar();
  69.     return 0;
  70. }
I just wrote and test the above code and it works. I hope it helps ;)
oh and if u are using pure C change cout to printf and class to structure XD, i think the other stay the same ? Anyone correct me if I am wrong..
Oct 11 '10 #4

Post your reply

Sign in to post your reply or Sign up for a free account.