c++ random number generation not random - c++

I'm trying to perform a random shuffle of a vector using Visual Studio 2013 C++. The following is the code that I have
static void shuffle(vector<int>& a){
int N = a.size();
unsigned long long seed = chrono::system_clock::now().time_since_epoch().count();
default_random_engine generator(seed);
for (int i = 0; i < N; i++){
uniform_int_distribution<int> distribution(0,(N-1)-i);
int r = i + distribution(generator);
swap(a[i], a[r]);
}
}
My problem is when I call this method multiple times in succession the shuffle is not random. What could be wrong with the code?
Any help would be much appreciated.

Uhm, I'm curious... why isn't the following sufficient for your needs:
static void shuffle(vector<int>& a)
{
// There are better options for a seed here, but this is what you used
// in your example and it's not horrible, so we'll stick with it.
auto seed (std::chrono::system_clock::now().time_since_epoch().count());
// Don't bother writing code to swap the elements. Just ask the standard
// library to shuffle the vector for us.
std::shuffle(std::begin(a), std::end(a), std::default_random_engine(seed));
}

std::shuffle dosent remove duplicates, it just swaps the positions of the random numbers generated.
How can I efficiently select several unique random numbers from 1 to 50, excluding x?
You can home cook your own shuffle code otherwise:
#include <ctime>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
void myShuffleWithNoRepeats( int random_once_buf[] , int size=100)
{
srand(time(0));
for (int i=0;i<size;i++)
{
// call made to rand( ) , stored in random_once_buf[ ]
random_once_buf[i]=rand() % 100;
//////////////////////////////////////////////////////////////////////////////////////
// The line below generates unique random number only once //
// //
// the variable i is the random_once_buffer[i] buffer array index count, //
// j is the check for duplicates, j goes through the random_once_buffer[i] buffer //
// from 0 to i at every iteration scanning for duplicates, reversing one step if one duplicate is found.. //
//////////////////////////////////////////////////////////////////////////////////////
for(int j=0;j<i;j++) if (random_once_buf[j] == random_once_buf[i]) i--;
}
cout<<" \n\n\n ";
}
int main(void)
{
const int size=100 ;
int random_once_buffer[100] ;
// Call made to function myShuffleWithNoRepeats( )
myShuffleWithNoRepeats( random_once_buffer , size );
// Loop to display the array random_once_buffer[ ]
for ( int i=0;i<size;i++) cout<<""<<random_once_buffer[i]<<"\t";
cout<<" \nPress any key to continue\n";
cin.ignore();
cin.get();
return 0;
}

Related

Array exercise code not working as intended

So here's my problem i'm writing a c++ code to basically randomly generate X amount of numbers between [0-100] and then create a 2D array with all the numbers found sorted by smallest->biggest
and print out each number found and how many times they are found.
this is the code i've written but there is a problem with it
whenever i print the array with the numbers and how many times each one is found no matter how many times one number is found it's the same for all of them
how can i fix that
#include <random>
#include <functional>
#include <iostream>
using namespace std;
std::default_random_engine generator;
std::uniform_int_distribution<int> data_element_distribution(0, 100);
auto random_element = std::bind(data_element_distribution, generator);
int main()
{
int size, i;
int different_numbers;
cout<<"Enter the size of the Linear List:";
cin>>size;
int LinearList[size], TempList[size];
for (i=0; i < size; i++)
{
int data_element = random_element(); //Filling the Linear List with random numbers
LinearList[i]=data_element;
TempList[i]=LinearList[i];
}
int j, temp;
for(j=size;j>1;j--)
{
for ( i=1; i<j; i++)
{
if(TempList[i]<TempList[i-1])
{
temp=TempList[i]; //Sorting numbers
TempList[i]=TempList[i-1];
TempList[i-1]=temp;
}
}
}
different_numbers=1;
int numbers[size];
int *Histogram;
Histogram=new int[different_numbers,1];
for (i=0;i<size-1;i++)
{
if(TempList[i]!=TempList[i+1])
{ //Finding the Size of the Histogram
numbers[different_numbers]=TempList[i]; //Counting how many Times each Number is found
Histogram[different_numbers,1]=1;
different_numbers++;
}
else
{
Histogram[different_numbers,1]++;
}
}
for(i=1;i<different_numbers;i++)
{
Histogram[i,0]=numbers[i]; //Printing numbers and Times found
cout<<Histogram[i,0];
cout<<" Is found "<<Histogram[i,1]<<" times."<<endl;
}
return 0;
}
edit: thank you guys for your comments and help i'll give it a try you're all life savers Xd

Adding together two arrays and print into third array

Before I start I must notice that I am a begginer in C++.
I have a code (see below), In this code I have two arrays with 10 random numbers but In tab_A numbers are the same like in tab_B - I don't know how to solve this. Also I don't know how to merge/add/sum these two arrays in new array tab_C and print result.
#include <iostream>
#include <cstdio>
#include <time.h>
#include <cstdlib>
using namespace std;
int gen() {
return rand() % 11;
}
int main()
{
int tab_A[10];
cout<<"TABLICA A DEBUG"<<endl;
srand (time(NULL));
for (int i=0; i<10; i++)
{
tab_A[i] = gen();
cout<<tab_A[i]<<endl;
}
int tab_B[10];
cout<<"TABLICA B DEBUG"<<endl;
srand (time(NULL));
for (int i=0; i<10; i++)
{
tab_B[i] = gen();
cout<<tab_B[i]<<endl;
}
int tab_C[10];
cout<<"TABLICA C DEBUG"<<endl;
int sumAB=0;
sumAB=tab_A[10]+tab_B[10];
tab_C[10]=sumAB;
cout<<tab_C[10]<<endl;
return 0;
}
In the code, you have called srand twice with the same seed. Hence, the numbers that will be randomly generated will be the same. If you want to generate random numbers it is advisable to set seed only once.
Also, there seems to be an issue in the code. C++ has 0-indexing. Hence, the lines
sumAB=tab_A[10]+tab_B[10];
tab_C[10]=sumAB;
cout<<tab_C[10]<<endl;
will give errors.
As the size of tab_C is 10 so the index of the last element would be 9.

Return value from string function

i have a string array that contains 20 words. I made a function that take 1 random word from the array. But i want to know how can i return that word from array. Right now i am using void function, i had used char type but it wont work. Little help here ? Need to make word guessing game.
CODE:
#include <iostream>
#include <time.h>
#include <cstdlib>
#include <stdlib.h>
#include <algorithm>///lai izmantotu random shuffle funckiju
#include <string>
using namespace std;
void random(string names[]);
int main() {
char a;
string names[] = {"vergs", "rokas", "metrs", "zebra", "uguns", "tiesa", "bumba",
"kakls", "kalns", "skola", "siers", "svari", "lelle", "cimdi",
"saule", "parks", "svece", "diegs", "migla", "virve"};
random(names);
cout<<"VARDU MINESANAS SPELE"<<endl;
cin>>a;
return 0;
}
void random(string names[]){
int randNum;
for (int i = 0; i < 20; i++) { /// makes this program iterate 20 times; giving you 20 random names.
srand( time(NULL) ); /// seed for the random number generator.
randNum = rand() % 20 + 1; /// gets a random number between 1, and 20.
names[i] = names[randNum];
}
//for (int i = 0; i < 1; i++) {
//cout << names[i] << endl; /// outputs one name.
//}
}
Make random return string. You also only need to seed the number generator once. Since you only want to get 1 random word from the array, you don't need a for loop.
string random(string names[]){
int randNum = 0;
randNum = rand() % 20 + 1;
return names[randNum];
}
Then, in the main function, assign a string variable to the return value of the random function.
int main() {
srand( time(NULL) ); // seed number generator once
char a;
string names[] = {"vergs", "rokas", "metrs", "zebra", "uguns", "tiesa", "bumba",
"kakls", "kalns", "skola", "siers", "svari", "lelle", "cimdi",
"saule", "parks", "svece", "diegs", "migla", "virve"};
string randomWord = random(names);
cout<<"VARDU MINESANAS SPELE"<<endl;
cin>>a;
return 0;
}
In your question as well as in the previous answer, you are running out of bounds accessing the names array:
int randNum = rand() % 20 + 1;
return names[randNum];
You are never accessing names[0] but instead reach behind the array when addressing names[20].
Additionally srand(time(NULL)) should be called only one time, on the beginning of main() function.
I'm not super familiar with strings, but you should be able to just declare random() as a string function.
Ex:
string random (string names[]);

Coin Change DP Algorithm Print All Combinations

The classic coin change problem is well described here: http://www.algorithmist.com/index.php/Coin_Change
Here I want to not only know how many combinations there are, but also print out all of them. I'm using the same DP algorithm in that link in my implementation but instead of recording how many combinations in the DP table for DP[i][j] = count, I store the combinations in the table. So I'm using a 3D vector for this DP table.
I tried to improve my implementation noticing that when looking up the table, only information from last row is needed, so I don't really need to always store the entire table.
However my improved DP solution still seems quite slow, so I'm wondering if there's some problem in my implementation below or there can be more optimization. Thanks!
You can run the code directly:
#include <iostream>
#include <stdlib.h>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, const char * argv[]) {
int total = 10; //total amount
//available coin values, always include 0 coin value
vector<int> values = {0, 5, 2, 1};
sort(values.begin(), values.end()); //I want smaller coins used first in the result
vector<vector<vector<int>>> empty(total+1); //just for clearing purpose
vector<vector<vector<int>>> lastRow(total+1);
vector<vector<vector<int>>> curRow(total+1);
for(int i=0; i<values.size(); i++) {
for(int curSum=0; curSum<=total; curSum++){
if(curSum==0) {
//there's one combination using no coins
curRow[curSum].push_back(vector<int> {});
}else if(i==0) {
//zero combination because can't use coin with value zero
}else if(values[i]>curSum){
//can't use current coin cause it's too big,
//so total combination for current sum is the same without using it
curRow[curSum] = lastRow[curSum];
}else{
//not using current coin
curRow[curSum] = lastRow[curSum];
vector<vector<int>> useCurCoin = curRow[curSum-values[i]];
//using current coin
for(int k=0; k<useCurCoin.size(); k++){
useCurCoin[k].push_back(values[i]);
curRow[curSum].push_back(useCurCoin[k]);
}
}
}
lastRow = curRow;
curRow = empty;
}
cout<<"Total number of combinations: "<<lastRow.back().size()<<endl;
for (int i=0; i<lastRow.back().size(); i++) {
for (int j=0; j<lastRow.back()[i].size(); j++) {
if(j!=0)
cout<<" ";
cout<<lastRow.back()[i][j];
}
cout<<endl;
}
return 0;
}
It seems that you copy too many vectors: at least the last else can be rewritten as
// not using current coin
curRow[curSum] = lastRow[curSum];
const vector<vector<int>>& useCurCoin = curRow[curSum - values[i]]; // one less copy here
// using current coin
for(int k = 0; k != useCurCoin.size(); k++){
curRow[curSum].push_back(useCurCoin[k]);
curRow[curSum].back().push_back(values[i]); // one less copy here too.
}
Even if it is readable to clean curRow = empty;, that may create allocation.
Better to create a function
void Clean(vector<vector<vector<int>>>& vecs)
{
for (auto& v : vecs) {
v.clear();
}
}

display 25 randomnumbers from an array

I have in C++ an array of 100 elements, so v[1], ... ,v[100] contains numbers. How can i display, 25 random numbers from this array? So i wanna select 25 random positions from this array and display the values.. How can i do this in C++?
Thanks!
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <vector>
using namespace std;
int aleator(int n)
{
return (rand()%n)+1;
}
int main()
{
int r;
int indexes[100]={0};
// const int size=100;
//int a[size];
std::vector<int>v;
srand(time(0));
for (int i=0;i<25;i++)
{
int index = aleator(100);
if (indexes[index] != 0)
{
// try again
i--;
continue;
}
indexes[index] = 1;
cout << v[index] ;
}
cout<<" "<<endl;
system("pause");
return 0;
}
The idea is that i have this code, and i generate 100 random numbers. What i want is an array with random 25 elements from those 100 generated.. But i don't know how to do that
Regards
Short Answer
Use std::random_shuffle(v.begin(),v.end()) to shuffle the array, and then display the first 25 elements.
Long Answer
First of all, the elements would be v[0]...v[99] (C++ uses 0-based indexing), not v[1]...v[100]. To answer your question, though, it depends on whether it is acceptable to repeat elements of the array or not. If you aren't worried about repeats, then simply use the index rand()%v.size(), repeatedly until you have selected a sufficient number of indices (25 in your question). If repeats are not acceptable, then you need to shuffle the array (by swapping elements at random), and then display the first (or last, or any contiguous region of) N elements (in this case N=25). You can use std::random_shuffle to shuffle the array. That does the bulk of the work for you. Once you've done that, just show 25 elements.
If you want to print 25 numbers of an array V you can use this code do:
int V[100]={1,2,5,...} ;
srand ( time (0) ) ;
for (int i=0;i<25;i++)
{
cout << V[rand() % 100 + 1]<<" " ;
}
I modified the version of Mehdi a little in order to make it choose differnet indexes
NOTE: This makes the algorithm not deterministic - it relies on the RNG.
int indexes[100]={0};
srand ( time (0) );
for (int i=0;i<25;i++)
{
int index = rand() % 100;
if (indexes[index] != 0)
{
// try again
i--;
continue;
}
indexes[index] = 1;
cout << v[index] ; cout << endl;
}