This question already has answers here:
Random array generation with no duplicates
(9 answers)
Closed 5 years ago.
I want to generate random numbers and save them in an array. that' all ! but here is the point, I want to avoid duplicating and not having a number two or more times in array.
my code :
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main()
{
int k, temp;
cin >> k;
int sym[k];
srand(time(NULL));
for (int i = 0; i < k; i++)
{
temp = rand() % 25 + 97;
for(int j=0; j<i; j++)
{
while(temp == sym[j])
{
temp = rand() % 25 + 97; // 25 means a and 122 means z
}
}
sym[i] = temp;
}
for(int i=0; i<k; i++)
{
cout << sym[i] << endl;
}
return 0;
}
I still get duplicated results.
I will use std::unordered_set to avoid duplicated
Random generator doesn't mean unique generation, collisions can always happen especially when the number of generated values is high and the bounds or limits for the generation is small...
to avoid duplicated elements replace this array
int sym[k];
by a set which is a container that doesn't allow duplicate entries...
std::set<int>
after that, you need to replace the logic because looping k times does not mean having k elements in the set, so you need to do a while loop until the size of the set reaches the limit k
Edit:
if you need some unsorted generated values, the instead of using a set, consider implementing an unordered_set
Related
I am new to c++. I am trying to generate 4 random unique numbers from 0 to 9. Here is my code:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<int> vect;
int randNums = 4;
int countSameNums = 0;
int randNumber;
srand(time(0)); // Initialize random number generator by setting the seed
// generate 4 random unique integers and insert them all into a vector
while (true){
randNumber = rand()%10;
for (int i = 0; i < vect.size(); i++){
if (randNumber == vect[i]){
countSameNums += 1;
}
}
if (countSameNums == 0){
vect.push_back(randNumber);
countSameNums = 0;
}
if (vect.size() == randNums)
break;
}
for (int el : vect){ // print out the content of the vector
cout << el <<endl;
}
}
I can compile the code without problems. However when I run it, sometimes it prints out the correct result, i.e. the 4 unique integers, but other times the program just hangs. I also notice that If I comment the line srand(time(0)) (my random seed) it prints 4 unique numbers every time, i.e. the program never hangs. The problem of course is that by commenting srand(time(0)) I get always the same sequence of unique numbers and I want a different sequence every run. Any idea on why this isn't working? thanks
It can take long before you get 4 different numbers. There is a simpler and more efficient way to get 4 unique numbers. Take a vector containung number from 0 till 9, shuffle it, take the first 4.
Anyhow the issue in your code is that once countSameNum is not 0 you will never reset it to 0. You only reset it when it is 0 already. Change it like this:
while (true){
randNumber = rand()%10;
countSameNums = 0;
for (int i = 0; i < vect.size(); i++){
if (randNumber == vect[i]){
countSameNums += 1;
}
}
if (countSameNums == 0){
vect.push_back(randNumber);
}
if (vect.size() == randNums)
break;
}
As this is rather error-prone you should rather use std::find to see if the number is already in the vector:
if (std::find(vect.begin(),vect.end(),randNumber) == vect.end()) vect.push_back(randNumber);
And as mentioned before, there are better ways to get unique random numbers.
I need to find a way to fill an array with random numbers without having duplicates,so i wrote this code and it works.My question is,is this code efficient and will it really have no duplicates? Thanks in advance!
#include <iostream>
#include <time.h>
#include <stdlib.h>
int main(void) {
srand(time(NULL));
std::size_t array_size=100;
int array[array_size];
for(int i=0;i<array_size;i++) {
array[i]=rand()%105+1;
for(int k=0;k<array_size;k++) { // Checks if there is a duplicate in the array //
if(i!=k) { // Don't check for the same array position //
if(array[i]==array[k]) { // If a duplicate is found,repeat the check process//
array[i]=rand()%105+1;
k=-1; // -1 so the for loop starts from zero //
}
}
}
}
return 0;
}
That approach works fine when the number of desired values is much less than the number of possible values. Most of time it won't produce a duplicate value, so it just keeps the one it produced. But when there isn't a lot of slack there are lots of duplicates; when this code gets close to the end it's generating a value between 1 and 106 when there are only six or seven or so acceptable values. So it ends up spinning its wheels.
Instead of doing all that looping, create an array that holds all of the possible values, randomly shuffle it, and throw out the extra ones:
int array[105];
for (int i = 0; i < 105; ++i)
array[i] = i + 1;
std::mt19937_64 mt;
std::shuffle(std::begin(array), std::end(array), mt);
for (int i = 0; i < 100; ++i)
std::cout << array[i] << '\n';
This question already has answers here:
How to make Random Numbers unique
(6 answers)
Closed 6 years ago.
As a part of code for a certain game I want to generate 4 unique random numbers into a vector.
This code works for some number of repeated plays and then application crashes (not responding window).
While I understand that if-condition prevents for-loop from inserting the same number into a vector, how much time does this for-loop takes until it generates unique numbers via rand() function?
How srand(time(NULL)) and rand() exactly work together to create random values depending on the system time?
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
using namespace std;
//plays bulls and cows
int main() {
srand(time(NULL));
string play="yes";
int nums=4; // number of values in an answer (must NOT exceed 10)
vector<int> answer;
while (play=="yes" || play=="YES" || play=="Y" || play=="Yes" || play=="y") { //plays the game
answer.push_back(rand()%10+1);
do { //fills vector with unique random numbers
for (int i=1; i<nums; i++) {
answer.push_back(rand()%10+1);
if (answer[i]==answer[i-1]) {
i=i-1;
continue;
}
}
} while (answer.size()!=nums);
for (int i=0; i<nums; i++) {
cout<<answer[i];
}
cout<<"Do you want to play again?"<<'\n';
cin>>play;
answer.clear();
} //game ends
if (play=="no" || play=="n" || play=="No" || play=="NO" || play=="N") { //terminates and checks for exceptions
cout<<"Thank you for playing!"<<'\n';
return 0;
} else {
cerr<<"Error: wrong input. Terminating."<<'\n';
return 0;
}
return 0; //safety return
}
Why do you add the new try into answer instead of temporary variable. If the variable is valid, then add it into the answer. In your case, i always keep at 1;
while (play=="yes" || play=="YES" || play=="Y" || play=="Yes" || play=="y") { //plays the game
int last_try=rand()%10+1;
answer.push_back(last_try);
do { //fills vector with unique random numbers
int new_try=rand()%10+1;
if (last_try!=new_try)
{
answer.push_back(new_try);
last_try=new_try;
}
} while (answer.size()!=nums);
for (int i=0; i<nums; i++)
{
cout<<answer[i]<<"\n";
}
cout<<"Do you want to play again?"<<'\n';
cin>>play;
answer.clear();
} //game ends
Assume that you must use std::vector (and not a std::set). The easiest way to fill your vector with random numbers is to check to see if the number has already been "seen" -- if not, then add it to the vector.
This can be accomplished by using an array of bool as a helper to determine if the number has been seen:
#include <vector>
#include <iostream>
#include <cstdlib>
int main()
{
std::vector<int> answer;
int num = 4;
// 10 numbers
bool seen[10] = {false};
// keeps track of numbers added
int numsAdded = 0;
while (numsAdded < num)
{
int numRand = rand()%10;
if ( !seen[numRand] )
{
// not seen, so add it to vector and update bool array and
// numsAdded
answer.push_back(numRand + 1);
seen[num] = true;
++numsAdded;
}
}
for (size_t i = 0; i < num; ++i)
std::cout << answer[i] << " ";
}
Live Example
The problem is you always push back the random value in your vector before checking if it's valid. Let's say your program generates these random value in order:
2, 6, 6, 7, 9, 10
What happens is you will insert 2 (i == 2), 6 (i == 3), 6 (i == 4), then realize 6 is repeated twice, so you go back one iteration (i == 3), but both your sixes are still in your vector. So now you will add 7 (i == 4) and you will exit the for loop with 5 values in your vector.
Then when you evaluate your do-while condition, your answer.size() won't ever equal 4 because it already is equal to 5. You are now stuck in an infinite loop, and your application crashes when it consumes all the available memory from your vector growing infinitely.
Also, you appear to have an error in your logic. To make sure you don't have a repeated value (and you are stuck with vectors), you should not only validate the last inserted value but the whole vector. Like this:
#include <algorithm>
if ( std::find(vector.begin(), vector.end(), item) != vector.end() )
do_this();
else
do that();
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
intent is to create an array of random numbers, and sort them in ascending order
array is created, but sorting does not work (numbers are printed in random order)
have i incorrectly applied sorting by reference?
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std;
void mySort(long x[])
{
long min(0), temp(0), minPosition(0), i(0), j(0);
min = x[0];
for (j = 0; j < 10; j++)
{
for (i = j; i < 10; i++)
{
if (x[i] < min)
{
min = x[i];
minPosition = i;
}
}
temp = x[minPosition];
x[minPosition] = x[j];
x[j] = temp;
}
}
int main()
{
long *myArray = new long[10];
int i(0);
srand((unsigned int)time(NULL));
for (i = 0; i < 10; i++)
{
myArray[i] = rand()%11;
}
mySort(myArray);
for (i = 0; i < 10; i++)
{
cout<<'['<<myArray[i]<<']'<<endl;
}
return 0;
}
One thing that stands out is that you need to reset min and minPosition every time your outer loop kicks off. At the moment, things will go badly wrong from the second iteration onwards.
Also, be aware that this (selection sort) is a rather inefficient way to sort a list. It runs in O(n^2) time, rather than O(n log n), which is what good sorting algorithms do (Quicksort, Heapsort, Mergesort).
Well if you dont know how to sort ...you can use sort() function as
// sort() Example using arrays.
#include <iostream>
#include <algorithm>
using namespace std;
const int SIZE = 7;
int main()
{
int intArray[SIZE] = {5, 3, 32, -1, 1, 104, 53};
//Now we call the sort function
sort(intArray, intArray + SIZE);
cout << "Sorted Array looks like this." << endl;
for (size_t i = 0; i != SIZE; ++i)
cout << intArray[i] << " ";
return 0;
}
Found in ~ #include <algorithm>
Parameter 1 myvector.begin() ~ The first parameter is where you will be putting a iterator(Pointer) to the first element in the range that you want to sort. The sort will include the element that the iterator points to.
Parameter 2 myvector.end() ~ The second parameter is almost like the first but instead of putting a iterator to the first element to sort you will be putting a iterator to the last element. One very important difference is that the search won’t include the element that this iterator points to. It is [First,Last) meaning it includes the first parameter in the sort but it doesn’t include the second parameter in the sort.
Parameter 3 myCompFunction() Optional ~ The third parameter is used to define how you do the search. For example if you have a struct that has 3 different variables in it.
This question already has answers here:
Generating m distinct random numbers in the range [0..n-1]
(11 answers)
Closed 8 years ago.
I need to generate 'random' int values that will be used as array indexes so they need to be uniqe for given interval.
LFSR seems to be perfect for this task but theres a catch: either array size ought to have size 2^n (in some cases it forces to allocate much more memory than required one(eg. data size 2100 - array size 4096)) or to skip generated numbers until proper value is found (waste of LFSR capabilities, in some cases generation time of index can be noticeable).
I have tried to create some formula to compute array indexes but I've failed, especially for small (<120) array sizes.
Is there any optimal (in terms of resources and computing time) solution to this problem?
Thanks in advance for answers!
May be it help you.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <ctime>
std::vector<int> random_interval_values(int b, int e)
{
int n = e - b;
std::vector<int>result(n);
for(int i = 1; i < n ; ++i)
{
int t = rand() % i; // t - is random value in [0..i)
result[i] = result[t]; // i-th element assigned random index-th value
result[t] =i; // and, random position assigned i value
}
// increment all values to b.
for(int i = 0; i < n; ++i) result[i] += b;
return result;
}
int main()
{
srand( time (NULL )) ;
int interval_begin = 7;
int interval_end = 15;
// [ interval_begin ... interval_end )
std::vector<int> v = random_interval_values( interval_begin, interval_end);
for(int i= 0; i < v.size(); ++i)
std::cout << v[i] << ' ';
std::cout << std::endl;
}