This question already has answers here:
rand() returns same values when called within a single function
(5 answers)
Closed 8 years ago.
I'm trying to write a simple function that generates an array with random integers.
I encountered with an interesting thing, when I run this program outputs -each cout
statements- seem the same.
However, when I am debugging and watching it step by step array values are changing.
Am I doing something wrong?
Thanks.
void generateRandomArray( int *&inputArray, int size){
if(inputArray != NULL){
delete []inputArray;
}
//create a new array
inputArray = new int [size];
//fill with random numbers
srand(unsigned (time (NULL)));
for (int i = 0; i < size ; i++)
inputArray[i] = (rand() % 100) ;
}
int main(){
//Variables
int *inputArray = NULL;
int size;
//Test
size = 10;
//first call
generateRandomArray( inputArray, size);
for(int i = 0 ; i < size; i++){
cout << inputArray[i] << endl;
}
cout << "------------------" << endl;
//second call
generateRandomArray( inputArray, size);
//output is the same with previous
for(int i = 0 ; i < size; i++){
cout << inputArray[i] << endl;
}
return 0;
}
The program runs too fast, srand(unsigned (time (NULL))); will get a seed having the same seconds (since epoch). Hence, the rand sequences are the same.
The problem is that if the calls to srand all happen withing the same second, the generator will be seeded with the same values and so generate the same sequence, always.
When you're debugging it will be slower, and allow time to pass and have different seed for the generator. When not debugging the time between calls will be too fast.
Don't call srand more than once, unless you know what you're doing. Put it at the start of the main function, and don't call it again.
Call srand(time(NULL)) and it will seed the current time and make a random number from it. Since time is changing all the time, it will give you a different number every time.
With C++11, you may use something like: (https://ideone.com/EIb0nY)
#include <iostream>
#include <random>
#include <vector>
std::vector<int> generateRandomArray(std::default_random_engine& generator, int size)
{
std::uniform_int_distribution<int> distribution(1, 100);
std::vector<int> res(size);
for (auto& e : res) {
e = distribution(generator);
}
return res;
}
int main()
{
std::default_random_engine generator;
const int size = 10;
//first call
for (auto e : generateRandomArray(generator, size)) {
std::cout << e << std::endl;
}
std::cout << "------------------" << std::endl;
//second call
for (auto e : generateRandomArray(generator2, size)) {
std::cout << e << std::endl;
}
return 0;
}
That use the new random facilities.
It avoids manual memory management (with std::vector).
Related
This is the problem I am working with
Using a loop and rand(), simulate a coin toss 10000 times
Calculate the difference between heads and tails.
Wrap the above two lines in another loop, which loops 1000 times.
Use an accumulator to sum up the differences
Calculate and display the average difference between the number of heads and tails.
The accumulator is not working the way I want It to? Very much a C++ Noob, for homework lol. Anyone help please?
Why am I using rand()????
second part of the assignment has us using the newer method (mt19937), just trying to tackle this bit first before moving on.
#include <iostream>
using namespace std;
int main() {
int heads = 0, tails = 0, num, total = 0;
srand(time(NULL));
for (int h = 0; h < 1000; h++) // Loop Coin Toss
{
for (int i = 0; i < 10000; i++) // COIN TOSS
{
int random = rand() % 2;
if (random == 0)
{
heads++;
}
else
{
tails++;
}
}
cout << abs((heads++ - tails++));
cin >> num;
total =+ num;
}
cout << "The average distance between is " << total / 1000 << endl;
cin.get();
return 0;
}
With your code, you never actually save the values that you need. And there's some unnecessary arithmetic that would throw off your results. This line:
cout << abs((heads++ - tails++)); increments the heads and tails variables, but they shouldn't be.
The next two lines make no sense. Why do you need to get a number from the user, and why do you add that number to your total?
Finally, this expression: total / 1000 performs integer division, which will throw off your results.
Those are the immediate issues I can spot in your code.
Next, we move on to your problem statement. What is an accumulator? To me, it sounds like you're supposed to have a class? It also reminds me of std::accumulate, but if that's what you intended, it would have said as much. Also, std::accumulate would require storing results, and that's not really necessary for this program. The code below performs the main task, i.e. it runs the necessary simulations and tracks results.
You'll notice I don't bother counting tails. The big average is also calculated as it goes since the total number of simulations is known ahead of time.
#include <cmath>
#include <iostream>
#include <random>
int flip_coin() {
static std::mt19937 prng(std::random_device{}());
static std::uniform_int_distribution<int> flip(0, 1);
return flip(prng);
}
int main() {
constexpr int tosses = 10'000;
constexpr int simulations = 1'000;
double diffAvg = 0.0;
for (int i = 0; i < simulations; ++i) {
int heads = 0;
for (int j = 0; j < tosses; ++j) {
if (flip_coin()) {
++heads;
}
}
diffAvg +=
std::abs(heads - (tosses - heads)) / static_cast<double>(simulations);
}
std::cout << "The average heads/tails diff is: " << diffAvg << '\n';
return 0;
}
What I ended up doing that seems to work for **THIS VERSION WITH RAND() (using the new method later) **
#include <iostream>
using namespace std;
int main()
{
int heads = 0, tails = 0, total = 0;
srand(time(NULL));
for (int h = 0; h < 1000; h++) // Loop Coin Toss
{
{
for (int i = 0; i < 10000; ++i) // COIN TOSS
if (rand() % 2 == 0)
++heads;
else
++tails;
total += abs(heads - tails);
}
}
cout << "The average distance between is " << total / 1000.0 << '\n';
cin.get();
return 0;
}
Hello I am trying to write a script that picks a random number and then excludes that number afterwards.
#include <iostream>
#include <ctime>
#include <random>
#include <iterator>
using namespace std;
random_device rd; // non-deterministic generator
mt19937 gen(rd()); // to seed mersenne twister.
uniform_int_distribution<> dist(1, 52); // distribute results between 1 and 6 inclusive.
int testFunc(int cardArray, int cardArray2, int k) {
cardArray[k] = dist(gen);
copy(begin(cardArray), end(cardArray), begin(cardArray2));
cardArray2[k] = 0;
bool exists = find(begin(cardArray2), end(cardArray2), cardArray[k]) != end(cardArray2);
cardArray[k] = dist(gen);
cout << i + 1 << ": " << cardArray[k] << " " << exists << endl;
return 0;
}
int main()
{
int cardArray[52] = { 0 };
int cardArray2[52] = { 0 };
int i = 0;
for (int n = 0; cardArray[n] == 0 && n < 52; n++) {
cardArray[i] = dist(gen);
copy(begin(cardArray), end(cardArray), begin(cardArray2));
cardArray2[i] = 0;
bool exists = find(begin(cardArray2), end(cardArray2), cardArray[i]) != end(cardArray2);
cardArray[i] = dist(gen);
cout << i + 1 << ": " << cardArray[i] << " " << exists << endl;
i++;
}
cout << endl;
cin.ignore();
return 0;
}
So there's a few problems so far. Here are the errors:
no instance of overloaded function "end" matches the argument list
no instance of overloaded function "begin" matches the argument list
expression must have pointer - to - object type
I just can't figure out what's wrong. The function itself works fine if it's just in main but I need to be able to call it.
Please tell me if I need to post more information.
You are taking in ints in you function not int*
int testFunc(int cardArray, int cardArray2, int k)
should be
int testFunc(int* cardArray, int* cardArray2, int k)
Unfortunately this will stop std::begin and std::end from working as they need an array and not a pointer. To pass the arrays to function you need to take them by reference. To do that we can use a template like:
template<typename T, std::size_t N, std::size_t M>
int testFunc(T (&cardArray)[N], T (&cardArray2)[M], int k)
Or we can skip using native arrays and use a std::array or std::vector
I use clock() in library to calculate excution time of a function, which is BubbleSort(..) function in my code below. But probleam is that the return execution time always = 0 (and it shows no unit, too).
This is my code:
#include <iostream>
#include <ctime>
using namespace std;
void BubbleSort(int arr[], int n)
{
for (int i = 1; i<n; i++)
for (int j = n-1; j >=i; j-- )
if (arr[j] < arr[j-1])
{
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
return;
}
int main()
{
int arr[] = {4,1,7,2,6, 17, 3, 2, 8,1};
int len = sizeof(arr)/sizeof(int);
cout << "Before Bubble Sort: \n";
for (int i=0;i<len;i++)
{
cout << arr[i] << " ";
}
clock_t start_s=clock(); // begin
BubbleSort(arr,len);
clock_t stop_s=clock(); // end
cout << "\nAfter Bubble Sort: \n";
for (int i=0;i<len;i++)
{
cout << arr[i] << " ";
}
// calculate then print out execution time - currently always returns 0 and I don't know why
cout << "\nExecution time: "<< (double)(stop_s - start_s)/CLOCKS_PER_SEC << endl;
//system("pause");
return 0;
}
I haven't known how to fix this problem yet .. So hope you guys can help me with this. Any comments would be very appreciated. Thanks so much in advanced !
As you have only a very small array, the execution time is probably much shorter than the resolution of clock(), so you either have to call the sort algorithm repeatedly or use another time source.
I modified your code as such and both start end stop have the value of 0. (ubuntu 13.10)
std::cout<<"start: "<<start_s<<std::endl;
BubbleSort(arr,len);
clock_t stop_s=clock(); // end
std::cout<<"stop: "<<stop_s<<std::endl;
you probably want something more like gettimeofday()
this http://www.daniweb.com/software-development/cpp/threads/120862/clock-always-returns-0 is an interesting discussion of the same thing. the poster concluded that clock()(on his machine) had a resolution of about 1/100 of a sec. and your code is probably ( almost certainly) running faster than that
I'm writing a program which is intended to compare the numbers in 2 arrays and output the number of matches that there are.
RandomNumber.h
#pragma once
#include <iostream>
#include <cstdlib>
#include <ctime>
class RandomNumber
{
public:
void randomNumber();
int actualRandomNumber;
};
RandomNumber.cpp
#include "RandomNumberGenerator.h"
void RandomNumber::randomNumber()
{
actualRandomNumber = rand() % 66 + 1;
}
Game.h
#include "RandomNumberGenerator.h"
class Game
{
private:
int randomNumbers[6];
public:
void generateRandomNumbers();
void compareNumbers2();
};
Game.cpp
void Game::generateRandomNumbers()
{
RandomNumber create;
for (int i = 0; i < 6; i++)
{
create.randomNumber();
randomNumbers[i] = create.actualRandomNumber;
}
for (int i = 0; i < 6; i++)
{
std::cout << randomNumbers[i] << " ";
}
}
void Game::compareNumbers2()
{
int k = 0;
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
if (randomNumbers[i] == randomNumbers[j])
{
k++;
}
}
}
if (k > 0)
{
std::cout << "Congratulations you matched: " << k << " number(s)";
}
if (k == 0)
{
std::cout << "Unfortunatly you matched: " << k << " numbers";
}
}
Main.cpp
#include "Game.h"
#include "RandomNumberGenerator.h"
int main()
{
Game play;
srand (time(NULL));
play.generateRandomNumbers();
std::cout << std::endl << std::endl;
play.generateRandomNumbers();
std::cout << std::endl << std::endl;
play.compareNumbers2();
system("pause");
return 0;
}
The problem I'm having isn't in creating the arrays and filling them, I get two filled arrays with 2 different sets of random numbers, but for some reason when comparing them the number of matches it tells me I have is always about 6 or 8 when I in fact rarely have more than one or two if that.
The most obvious problem is that you only have one array.
class Game
{
...
int randomNumbers[6];
Where did you think the second array was?
Based on your code, I saw only 1 array. And in the function compareNumber2(), you compare each number with it once. Therefore, the result is the number of elements (e.g, 6).
Looking at code, I can say you will be getting 6 matches all the time, since you randomNumbers array will be overwritten in second step (when you try to generate random numbers second time)
There are actually two problems bigger and smaller:
You're comparing your array int randomNumbers[6] with itself.
Please don't call the object create. Its very wrong habit. Call the object of class RandomNumber i.e a randomNumber and take your random number from it like:
randomNumber.getValue()
Usually try to call the methods with verbs and objects with nouns it will be more natural don't you think?
You do no not compare two arrays. You compare one array, data member of class Game, with itself. You simply fill it two times.
I am having a hard time with translating this pseudocode into C++. The goal is to generate random numbers into A[] and sort them using insertion sort then get the execution time in milliseconds. Insertion sort would run for m=5 times. Each n value should be 100, 200, 300,....,1000. So for example if n=100 then that would run 5 times with 5 different sets of random numbers, then do the same thing for n=200, etc...
I have already written my insertion sort and that works so I did not include it. I am really just having trouble translating this pseudocode into something I can work with. I included my attempt and the pseudocode so you can compare.
Pseudocode:
main()
//generate elements using rand()
for i=1 to 5
for j=1 to 1000
A[i,j] = rand()
//insertion sort
for (i=1; i<=5; i=i+1)
for (n=100; n<=1000; n=n+100)
B[1..n] = A[i,n]
t1 = time()
insertionSort(B,n)
t2 = time()
t_insort[i,n] = t2-t1
//compute the avg time
for (n=100; n<=1000; n=n+100)
avgt_insort[n] = (t_insort[1,n]+t_insort[2,n]+t_insort[3,n]+...+t_insort[5,n]+)/5
//plot graph with avgt_insort
This is my attempt:
I am confused with t_insort and avgt_insort, I did not write them to C++. Do I make these into new arrays? Also take I am not sure if I am doing my time correctly either. I am sorta new at this running time thing so I have never actually wrote it into code yet.
#include <iostream>
#include <stdlib.h>
#include <time.h>
int main()
{
int A[100];
for(int i=1; i<=5; i++)
{
for(int j=1; j<=1000; j++)
{
A[i,j] = rand();
}
}
for(int i=0;i<=5; i++)
{
for(int n=100; n<=1000; n=n+100)
{
static int *B = new int[n];
B[n] = A[i,n];
cout << "\nLength\t: " << n << '\n';
long int t1 = clock();
insertionSort(B, n);
long int t2 = clock();
//t_insort
cout << "Insertion Sort\t: " << (t2 - t1) << " ms.\n";
}
}
for(int n=100; n<=1000; n=n+100)
{
//avt_insort[n]
}
return 0;
}
The pseudocode is relatively close to a C++ code with some syntactic changes. Note that this C++ code is a straightforward "translation". A better solution would be to use containers from C++ standard library.
int main()
{
int A[6][1001], B[1001]; //C++ starts indexing from 0
double t_insort[6][1000]; //should be of return type of time(), so maybe not double
int i,j,n;
for( i=1;i<=5;i++) //in C++ it is more common to start from 0 for(i=0;i<5;i++)
for(j=1;j<=1000;j++)
A[i][j] = rand(); //one has to include appropriate header file with rand()
//or to define his/her own function
for (i=1; i<=5; i++)
for (n=100; n<=1000; n=n+100)
{
B[n]=A[i][n];
t1 = time(); //one has firstly to declare t1 to be return type of time() function
insertionSort(B,n); //also this function has to be defined before
t2=time();
t_insort[i][n]=t2-t1; //this may be necessary to change depending on exact return type of time()
}
}
for (n=100; n<=1000; n=n+100)
for(i=1;i<=5;i++)
avgt_insort[n] += t_insort[i][n]
avgt_insort[n]/=5;
//plot graph with avgt_insort
A[i,j] is the same as A[j] (comma operator!), and wouldn't work.
You might want to declare a two dimensional array for A or even better an appropriate std::array:
int A[100][1000];
std::array<std::array<int,1000>, 100> A; // <- prefer this for c++
Also allocating B right away inside the for loop doesn't look right:
static int *B = new int[n];
and
B[n] = A[i,n];
won't work either as you intend (see above!).