Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


storing random unique values in a vector


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
16 replies to this topic

#1 phil67rpg   Members   -  Reputation: 767

Like
0Likes
Like

Posted 15 November 2012 - 05:36 PM

I have done a lot of research on this problem. I am trying to store random values in a vector. I want to generate a random value from 1 to 9. Then I want to fill a vector with 5 unique random values. Then I want to output the values.
here is the code I am using.
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> v;


    for(int i=1;i<10;i++)
        v.push_back(i);

    random_shuffle(v.begin(), v.end());

    for(vector<int>::iterator itr=v.begin(); itr != v.end(); ++itr)
        cout << *itr << endl;


}
basically this code takes the numbers from 1 to 9 and shuffles them and then outputs them.my question is how do I shuffle a sequence of random numbers that do not repeat. Let me know if you need more explanation.


Sponsor:

#2 frob   Moderators   -  Reputation: 22227

Like
0Likes
Like

Posted 15 November 2012 - 05:45 PM

It looks like your code is doing what you expect; you feed in ten digits, shuffle them, and output the result.


Can you give some examples of input and output? What do you mean by "a sequence of random numbers that do not repeat" ? Individual digits frequently repeat themselves in random number sequences.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I write about assorted stuff.


#3 fastcall22   Crossbones+   -  Reputation: 4376

Like
1Likes
Like

Posted 15 November 2012 - 05:46 PM

How do I shuffle a sequence of random numbers that do not repeat

Hi Phil,

By default, the seed used by the random number generator is set to a default value each time the program starts. This causes the same sequence of random numbers. You will need to reseed the random number generator before using it.

Use the time function under the ctime header to get the current time (number of seconds since the epoch), then use that to seed the random number generator using srand:
srand( (unsigned)time(0) );

Edited by fastcall22, 15 November 2012 - 05:47 PM.

c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#4 Servant of the Lord   Crossbones+   -  Reputation: 20300

Like
0Likes
Like

Posted 15 November 2012 - 05:46 PM

What you have *shouldn't* repeat, except for one thing: You never seed the random number generator.

std::random_shuffle, if I recall correctly, uses rand() under the hood (unless you pass a different generator) - though I'm not sure if that changes for C++11, nor if it's standardized that rand() is default.

Since you never call srand(), rand() is seeded with 0 - thus the random shuffle repeats each time.
Instead, seed srand() with time(NULL) at the start of your program, and hopefully the result will be more suiting to your tastes.

[Edit:] Three posts within 60 seconds of each other. =)

Edited by Servant of the Lord, 15 November 2012 - 05:48 PM.

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#5 phil67rpg   Members   -  Reputation: 767

Like
0Likes
Like

Posted 15 November 2012 - 06:05 PM

It looks like your code is doing what you expect; you feed in ten digits, shuffle them, and output the result.


Can you give some examples of input and output? What do you mean by "a sequence of random numbers that do not repeat" ? Individual digits frequently repeat themselves in random number sequences.

well I made some changes to my code.
input should be a random number from 1 to 9
output should be a list of random numbers that do not repeat.
such as: 3 7 8 9 1 2 5 4 6
#include <iostream>
#include <vector>
#include <algorithm>
#include <time.h>

using namespace std;

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

	vector<int> v;

	for(int i=1;i<10;i++)
	{
	int j=rand()%9+1;  
	v.push_back(j);
	}

    random_shuffle(v.begin(), v.end());

    for(vector<int>::iterator itr=v.begin(); itr != v.end(); ++itr)
        cout << *itr << endl;


}




#6 Álvaro   Crossbones+   -  Reputation: 13652

Like
0Likes
Like

Posted 15 November 2012 - 06:18 PM

input should be a random number from 1 to 9
output should be a list of random numbers that do not repeat.
such as: 3 7 8 9 1 2 5 4 6

What's the connection between the input and the output? You want to only produce 9 different sequences?

#7 phil67rpg   Members   -  Reputation: 767

Like
0Likes
Like

Posted 15 November 2012 - 06:32 PM

input should be a list of numbers from 1 to 9 generated randomly that can repeat
output should be a list of numbers from 1 to 9 that do not repeat
input: 1,3,4,2,1,5,5,9,8
output: 3,1,4,2,5,9,8


#8 Álvaro   Crossbones+   -  Reputation: 13652

Like
0Likes
Like

Posted 15 November 2012 - 06:37 PM

Are you trying to skip numbers that have appeared already? You example isn't quite right...

#9 rip-off   Moderators   -  Reputation: 8516

Like
0Likes
Like

Posted 15 November 2012 - 06:37 PM

The output list contains a randomised ordering of the unique set of elements in the input list?

#10 Servant of the Lord   Crossbones+   -  Reputation: 20300

Like
0Likes
Like

Posted 15 November 2012 - 06:42 PM

input should be a list of numbers from 1 to 9 generated randomly that can repeat
output should be a list of numbers from 1 to 9 that do not repeat
input: 1,3,4,2,1,5,5,9,8
output: 3,1,4,2,5,9,8

Your code should already do that. What is the current result that you are getting that you don't want?
Why does your input have non-unique variables? Where is this input coming from - the player or is it generated by your code?

Since we are all failing to understand, could you give a bigger-picture description of why you want this, and how you intend to use it?
It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#11 fastcall22   Crossbones+   -  Reputation: 4376

Like
1Likes
Like

Posted 15 November 2012 - 07:55 PM

input should be a list of numbers from 1 to 9 generated randomly that can repeat
output should be a list of numbers from 1 to 9 that do not repeat
input: 1,3,4,2,1,5,5,9,8
output: 3,1,4,2,5,9,8

If this is the case Phil, then you need to be generating a random set of integers from 1 to 9, not a sequence of integers from 1 to 9:
    // v is always:  1 2 3 4 5 6 7 8 9      (no duplicates, ever)
    for(int i=1;i<10;i++)
        v.push_back(i);
    random_shuffle(v.begin(),v.end());   // (elements might be in a random order, but there still aren't any duplicates)

    // v could be:  9 1 8 6 7 4 6 3 2 
    for(int i=1;i<10;i++)
        v.push_back( rand()%9 + 1 );     // (may have duplicates)
(See the reference on rand. rand() returns an integer between 0 and RAND_MAX -- usually 32767 -- and the modulus wraps that around the range between 0 and 8, and adding one brings it between 1 and 9.)

Then, you'll need to include algorithm, such that you can use sort to move duplicates together, then use unique to move the duplicate values to the back. Once the unique values are in front, you can remove the duplicates from v by using the iterator returned by unique:
    sort( v.begin(), v.end() );
    v.erase( unique(v.begin(),v.end()), v.end() );

Edit:
Hurr durr, I read can documentation good.

Edited by fastcall22, 16 November 2012 - 12:03 PM.

c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#12 Servant of the Lord   Crossbones+   -  Reputation: 20300

Like
0Likes
Like

Posted 15 November 2012 - 08:59 PM

@fastcall: Ah, good comprehension. I was misunderstanding what he meant.
It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#13 BitMaster   Crossbones+   -  Reputation: 4229

Like
0Likes
Like

Posted 16 November 2012 - 05:44 AM

Unless I'm mistaken, std::unique only removes consecutive duplicates. That means a sequence like "1 2 1" is still completely possible. Or am I misunderstanding some constraint as well?

#14 Khatharr   Crossbones+   -  Reputation: 3030

Like
-1Likes
Like

Posted 16 November 2012 - 06:56 AM

Unless I'm mistaken, std::unique only removes consecutive duplicates. That means a sequence like "1 2 1" is still completely possible. Or am I misunderstanding some constraint as well?


I was thinking that too, but deferred since I'm too lazy to look it up.

...

Nope. Still too lazy. Sry
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

#15 KnolanCross   Members   -  Reputation: 1334

Like
0Likes
Like

Posted 16 November 2012 - 07:03 AM

The easiest way to do it is to insert the numbers in a std::set (so there will be no duplicates), then copy to a std::vector and finally shuffle then.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).


#16 rip-off   Moderators   -  Reputation: 8516

Like
1Likes
Like

Posted 16 November 2012 - 07:04 AM

Yes, std::unique only handles consecutive duplicates. The input list could be sorted beforehand, or alternatively it could be changed to a std::set, preventing duplicates occurring in the first place.

#17 Servant of the Lord   Crossbones+   -  Reputation: 20300

Like
0Likes
Like

Posted 16 November 2012 - 11:44 AM

Unless I'm mistaken, std::unique only removes consecutive duplicates. That means a sequence like "1 2 1" is still completely possible.

Which is what I think the OP was wanting. His current method (generate array from 0 to 9, shuffle array) provides unique elements already.

If the OP *wants* repeats, but just not two in a row of the same number, std::unique would help with that.
Otherwise, I have no clue what the OP wants, since his original code already gives him only uniques.
It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS