Adventure for learning basics and more in c++ (Total noob). Now i made a Playground Array for all the fields to visit, but when it comes to the rand() function in a for loop it repeats the Nummber so it's not random generated. Some ideads to fix this issue? Note that iam not very into the rand func.
Thanks in advance!
Here is my code
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
//**SETTINGS**
//Häufigkeit von field_type
#define VILLAGE 5
#define TOWN 2
int main()
{
//** THE PLAYGROUND **
struct field {
bool status;
string field_type;
};
int x = 5;
int y = 5;
field playground[5][5];
//Playground Typen definition
int village_counter = 0;
int town_counter = 0;
int x2 = 0;
int y2 = 0;
for (int counter = 0; counter < x * y; counter++) {
int Nummer;
srand(time(NULL));
Nummer = rand() % 4 + 1; // generates always the same number!
switch (Nummer) {
case 1:
village_counter++;
if (VILLAGE >= village_counter) {
playground[x2][y2].field_type = "VILLAGE";
}
else {
goto a_switch;
}
break;
case 2:
town_counter++;
if (TOWN >= town_counter) {
playground[x2][y2].field_type = "TOWN";
}
else {
goto b_switch;
}
break;
case 3:
a_switch:
playground[x2][y2].field_type = "GRASSLAND";
break;
case 4:
b_switch:
playground[x2][y2].field_type = "FOREST";
break;
}
x2++;
if (x2 == x) {
x2 = 0;
y2++;
}
}
//For test usage of all Field's
x2 = 0;
y2 = 0;
for (int counter = 0; counter < x * y; counter++) {
cout << counter << ": Field_TYPE = " << playground[x2][y2].field_type << endl;
x2++;
if (x2 == x) {
x2 = 0;
y2++;
}
}
}
time requests the current time in seconds as an integer. if your program takes less than a second to execute, then you will "seed" the random number generator with the same value every time. pseudo random number generators (i.e. your rand() call) return a deterministic series of values based on this state you seeded.
as #Scheff said, you're much better off just seeding once (probably at the beginning of the program) and then just calling rand() when you need it. note that srand and rand are old historical artifacts from C, and you're much better off using more modern generators that come with recent C++ compilers
see the docs on c++ random number generators for more information
Related
I'm trying to create a array of prime numbers done by calculation. As a project to learn coding. Ultimately to build my own math library so this is something I can add onto at a variety of levels as I learn to code c++.
The following is code that works great for printing prime numbers to the screen based on the search range, but my totalPrimes iterator is stuck at 1. So each time it places the last prime found in the PrimeNumbers[1] position.
Any advice would be awesome.
#include <iostream>
#include <array>
std::array<long, 10000000> PrimeNumbers={0};
void isPrime(long x);
int main() {
for (long i = 1; i < 10; i++) {
isPrime(i);
}
for(int h = 0; h < 10; h++) {
std::cout << "\nSecond Prime is : " << PrimeNumbers[h];
}
}
void isPrime(long x) {
int count(0), totalPrimes(0);
for (long a = 1; a < x; a++) {
if ((x % a) == 0) {
count += 1;
}
}
if (count == 1) {
++totalPrimes;
std::cout << '\n' << x << " is a Prime number";
PrimeNumbers[totalPrimes] = x;
}
}
You're initializing totalPrimes to 0 every time the function runs. You would need to have totalPrimes as a global variable, or better yet (because global variables can become problematic), set it equal to the first available member of PrimeNumbers before you do anything else in that function.
Keep track of a position along with your PrimeNumbers array.
size_t nLastPos=0;
...
for(size_t x = 0; 1000 > x; ++x)
{
if(isPrime(x))
{
PrimeNumbers[nLastPos++] = x;
}
}
for(size_t i = 0; nLastPos > n; ++n)
{/* print out number PrimeNumbers[n] */ }
It looks like you're having some trouble with variable scoping. The reason for your problem (as I noted in the comment) is that totalPrimes is local, so you're creating a new integer variable and setting it to 0 every time the function is called.
However, you've made PrimeNumbers global and are having the isPrime function modify it, which doesn't look like good practice.
All of this can be fixed with a little restructuring to make the code nicer:
#include <iostream>
#include <array>
bool isPrime(long x);
int main() {
std::array<long, 10000000> PrimeNumbers={0};
int totalPrimes = 0;
for (long i = 1; i < 10; i++) {
if (isPrime(i)) {
std::cout << '\n' << i << " is a Prime number";
PrimeNumbers[totalPrimes++] = i;
}
}
for(int h = 0; h < 10; h++) {
std::cout << h << " Prime is : " << PrimeNumbers[h] << std::endl;
}
}
bool isPrime(long x) {
int count(0);
for (long a = 1; a < x; a++) {
if ((x % a) == 0) {
count += 1;
}
}
return count == 1;
}
Your program can be re-structured little bit to make it easier to follow and debug.
Don't put things in isPrime other than the logic to decide whether a number is prime. Make sure it returns a bool. This will make the function a bit simpler and easier to debug.
Use the return value of isPrime in the calling function to perform other bookkeeping tasks.
The logic you have used to check whether a number is prime is incorrect. That needs to be fixed.
Here's an updated version of your posted code.
#include <iostream>
#include <array>
#include <cmath>
std::array<long, 10000000> PrimeNumbers={0};
bool isPrime(long x);
int main()
{
int totalPrimes = 0;
for (long i = 1; i < 10; i++)
{
if ( isPrime(i) )
{
std::cout << i << " is a Prime number" << std::endl;
PrimeNumbers[totalPrimes] = i;
++totalPrimes;
}
}
}
bool isPrime(long x) {
// 1, 2, and 3 are primes.
if ( x <= 3 )
{
return true;
}
// Even numbers are not primes.
if ( x % 2 == 0 )
{
return false;
}
// Check the rest.
long end = (long)std::sqrt(x);
for (long a = 3; a < end; a += 2) {
if ((x % a) == 0)
{
return false;
}
}
return true;
}
and its output:
1 is a Prime number
2 is a Prime number
3 is a Prime number
5 is a Prime number
7 is a Prime number
9 is a Prime number
Everybody is talking about how your totalPrimes variable is reset each time the function is called, and this is obviously true. You could return the value from the function and increment it from main, you could use global variables having the variable being defined outside of the function so that it's not reset each time inside the function or you could use
A static variable!
Take a look at this simple case. I have a function called up_two which increases the value of by two each time the function is called. The static variable int value has a memory of each time the function up_two() is called which increments value by two each time. If I were to use a just an integer it would always reset the value and have it be zero, which is what I initially defined it to be.
The advantage of using a static variable is that I can count how many times a function has been called, and I can keep my counter specific to a particular function.
#include <iostream>
using namespace std;
void up_two();
int main()
{
for(int i = 0; i < 10; i++)
{
up_two();
}
return 0;
}
void up_two()
{
static int value = 0;
cout << value << endl;
value += 2;
}
This program doesn't solve the particular problem that you want to solve, but if you figure out how the static variable is working, it should make your workflow easier.
The magic line here is this:
static int value = 0;
With it like this my program prints the following:
0
2
4
6
8
10
12
14
16
18
Without the static declaration, you just get 10 lines of zeroes
which is troublesome.
Hope that helps you optimize your program the way you want it to be.
I'm trying to understand possible optimization methods for the bubble sort algorithm. I know there are better sorting methods, but I'm just curious.
To test the efficiency I'm using std::chrono. The program sorts a 10000 number long int array 30 times and prints the average sorting time. The numbers are picked randomly(up to 10000) in every iteration. Here is the code, with no optimization:
#include <iostream>
#include <ctime>
#include <chrono>
using namespace std;
int main() {
//bubble sort
srand(time(NULL));
chrono::time_point<chrono::steady_clock> start, end;
const int n = 10000;
int i,j, last, tests = 30,arr[n];
long long total = 0;
bool out;
while (tests-->0) {
for (i = 0; i < n; i++) {
arr[i] = rand() % 1000;
}
j = n;
start = chrono::high_resolution_clock::now();
while(1){
out = 0;
for (i = 0; i < j - 1; i++) {
if (arr[i + 1] < arr[i]) {
swap(arr[i + 1], arr[i]);
out = 1;
}
}
if (!out) {
break;
}
//j--;
}
end = chrono::high_resolution_clock::now();
total += chrono::duration_cast<chrono::nanoseconds>(end - start).count();
cout << "Remaining :"<<tests << endl;
}
cout << "Average :" << total / static_cast<double>(30)/1000000000<<" seconds"; // tests(30) + nanosec -> sec
cin.sync();
cin.ignore();
return 0;
}
I get 0.17 seconds average sorting time.
If I uncomment line 47(j--;) to avoid comparing numbers already sorted I get 0.12 sorting time which is understandable.
If I remember the last position where a swap took place, I know that after that index, elements are sorted, and can thus sort up to that position in further iterations. It's better explained in the second part of this post: https://stackoverflow.com/a/16196115/1967496.
This is the code that implements the new possible optimization:
#include <iostream>
#include <ctime>
#include <chrono>
using namespace std;
int main() {
//bubble sort
srand(time(NULL));
chrono::time_point<chrono::steady_clock> start, end;
const int n = 10000;
int i,j, last, tests = 30,arr[n];
long long total = 0;
bool out;
while (tests-->0) {
for (i = 0; i < n; i++) {
arr[i] = rand() % 1000;
}
j = n;
start = chrono::high_resolution_clock::now();
while(1){
out = 0;
for (i = 0; i < j - 1; i++) {
if (arr[i + 1] < arr[i]) {
swap(arr[i + 1], arr[i]);
out = 1;
last = i;
}
}
if (!out) {
break;
}
j = last + 1;
}
end = chrono::high_resolution_clock::now();
total += chrono::duration_cast<chrono::nanoseconds>(end - start).count();
cout << "Remaining :"<<tests << endl;
}
cout << "Average :" << total / static_cast<double>(30)/1000000000<<" seconds"; // tests(30) + nanosec -> sec
cin.sync();
cin.ignore();
return 0;
}
Note lines 40 and 48. And here comes the problem: The average time is now again around 0.17 seconds.
Is there a problem in my code, or am I missing something ?
Update:
I did sorting with 10 times more numbers and get now following results:
No optimization: 19.3 seconds
First optimization(j--): 14.5 seconds
Second (supposed) optimization(j=last+1): 17.4 seconds;
From my understanding, the second method should be in any case better than the first, but the numbers tell something else.
Well... The problem is that there might not be the right or wrong answer to this question.
First of all, when you're comparing only 10000 elements, you cannot really call it an effeciency test. Try comparing much higher number of elements - maybe 500000 (although you will probably need to alocate an array dynamicaly for that).
Second of all, it might be the compiler. Compilers often try to optimize things so that the program execution will run smoother and faster.
I'm working on a fibonacci algorithm for really big numbers (100k th number). I need to make this run faster though, but just a couple of seconds and I ran out of ideas. Is there any way to make it faster? Thanks for help.
#include <iostream>
using namespace std;
int main() {
string elem_major = "1";
string elem_minor = "0";
short elem_maj_int;
short elem_min_int;
short sum;
int length = 1;
int ten = 0;
int n;
cin >> n;
for (int i = 1; i < n; i++)
{
for (int j = 0; j < length; j++)
{
elem_maj_int = short(elem_major[j] - 48);
elem_min_int = short(elem_minor[j] - 48);
sum = elem_maj_int + elem_min_int + ten;
ten = 0;
if (sum > 9)
{
sum -= 10;
ten = 1;
if (elem_major[j + 1] == NULL)
{
elem_major += "0";
elem_minor += "0";
length++;
}
}
elem_major[j] = char(sum + 48);
elem_minor[j] = char(elem_maj_int + 48);
}
}
for (int i = length-1; i >= 0; i--)
{
cout << elem_major[i];
}
return 0;
}
No matter how good optimizations you perform on a given code, without changing the underlying algorithm you can only optimize it marginally. Your approach is with linear complexity and for big values it will quickly become slow. A faster implementation of Fibonacci numbers is by doing matrix exponentiation by squaring on the matrix:
0 1
1 1
This approach will be with logarithmic complexity which is asymptotically better. Perform a few exponentiations of this matrix and you'll notice that the n + 1st Fibonacci number is at its lower right corner.
I suggest you use something like cpp-bigint (http://sourceforge.net/projects/cpp-bigint/) for your big numbers.
The code would look like this then
#include <iostream>
#include "bigint.h"
using namespace std;
int main() {
BigInt::Rossi num1(0);
BigInt::Rossi num2(1);
BigInt::Rossi num_next(1);
int n = 100000;
for (int i = 0; i < n - 1; ++i)
{
num_next = num1 + num2;
num1 = std::move(num2);
num2 = std::move(num_next);
}
cout << num_next.toStrDec() << endl;
return 0;
}
Quick benchmark on my machine:
time ./yourFib
real 0m8.310s
user 0m8.301s
sys 0m0.005s
time ./cppBigIntFib
real 0m2.004s
user 0m1.993s
sys 0m0.006s
I would save some precomputed points (especially since you are looking for really big numbers)
ie say I saved 500th and 501st fib number. Then if some one asks me what is 600th fib? I would start computing from 502 rather than from 1. This would really save time.
Now the question how many points you would save and how would select the points to save?
The answer to this question totally depends on the application and probable distribution.
I have an assignment where I need to calculate the probability that two people share the same birthday for a given room size (in my case 50) over many trials (5000). I have to assign the birthdays randomly to the number of people in the room. The difference is I need to use a Boolean function to check the if the Birthdays are the same. I cannot figure why my outputs are off, but I believe it has something to do with two of my loops.
>
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
bool SameBirthday(int birthdays[], int numpeople);
const int MAX_PEOPLE = 50;
const double NUM_TRIALS = 5000.0;
const int DAYS_IN_YEAR = 365;
int main(void)
{
int numMatches = 0;
int people = 2;
int trial = 0;
int numpeople = 0;
int i = 0;
int birthdays[MAX_PEOPLE];
bool Match;
double Probability = 0;
srand(time(0));
for (people = 2; people <= MAX_PEOPLE; people++)
{
numMatches = 0;
for (trial = 0; trial < NUM_TRIALS; trial++)
{
for (i = 0; i < people; i++)
{
birthdays[i] = (rand() % 365 + 1);
numpeople = i;
}
if ((SameBirthday(birthdays, numpeople) == true))
{
numMatches++;
}
}
Probability = (numMatches / NUM_TRIALS);
cout << "For " << people << ", the probability of two birthdays is about " << Probability << endl;
}
}
bool SameBirthday(int birthdays[], int numpeople)
{
bool match = false;
int numberofmatches = 0;
//Use this function to attempt to search the giving array birthdays and count up number of times
//at least two people have matching birthdays for any given 1 trial
for (int SpaceOne = 0; SpaceOne < numpeople; SpaceOne++)
{
for (int SpaceTwo = SpaceOne + 1; SpaceTwo < numpeople; SpaceTwo++)
{
if (birthdays[SpaceTwo] == birthdays[SpaceOne])
{
return true;
}
}
}
return false;
}
I know that the code has errors in certain spots that was because I started trying different things, but any help would be appreciated.
EDIT- My only issue now is that for my output I have a zero for the probability of 2 people in the room have a birthday, which is not right. It seems like my outputs are like a person off, the probability of 2 people is shown as the probability for three people and so on.
EDIT(8-31-2015): I also forgot to mention that my Professor stated that my SameBirthday function needed the parameters: birthday[], and numpeople so I cannot use MAX_PEOPLE as a parameter. My professor also suggested using a triple nested for loop within the main body of the function. I believe what is making my output off by one for each person relates to the triple nested for loop, but I am unsure what would cause the issue.
Just do it like this:
bool SameBirthday(int birthdays[], int numPeople)
{
for(int x=0; x<numPeople; x++){
for(int y=0; y<numPeople; y++){
if(birthdays[x] == birthdays[y])
return true;
}
}
return false;
}
Your logic in your nested loop is wrong..
for (SpaceOne = 0; SpaceOne < numpeople - 1; SpaceOne++)
for (SpaceTwo = SpaceOne + 1; SpaceTwo < numpeople; SpaceTwo++)
Your inner loop is skipping n number of checks where n equals SpaceOne.
By the way, this is not C programming. You can declare variable within a for-loop.
I see two problems with the actual functionality. First, SameBirthday needs to return a value (false) when there is no birthday match. You can do that at the end of the function, after all the loops are done.
Second, you need to increment numMatches when you find a match.
To clarify issues from other parts of your coding. I think this is what your school wants.
int main(){
//All your variables
for(int x=0; x<NUM_TRIALS; x++){
for(int y=0; y< MAX_PEOPLE; y++){
birthdays[y] = (rand() % 365 + 1);
}
if(SameBirthday(birthdays, MAX_PEOPLE) == true)
numMatches ++;
}
Probability = ((double)numMatches / NUM_TRIALS);
cout << "For " << people << ", the probability of two birthdays is about "
<< Probability << endl;
}
NUM_TRIALS to generate 5000 datasets. Hence, you generate birthday for 50 students 5000 times. For each trial within a class of 50, you check whether there are 2 person with same birthday. If there is, numMatches + 1.
After 5000 trials, you get the probability.
Your other problem is that numpeople will always be the number of people minus 1. You don't actually need that variable at all. Your "people" variable is the correct number of people.
How do I create a program that generates ten random numbers from 1 -> RAND_MAX?
RAND_MAX must be a number input by the user.
#include <iostream>
#include <stdlib.h>
int main()
{
using namespace std;
int x;
int y;
Random:
{
x = rand();
cout << x << endl;
}
y = y + 1;
if (y == 10) {
return 0;
}
goto Random;
}
Disclaimer: rand is a quick and dirty way to generate random numbers, as it may not generate numbers perfectly uniformly and you'll run into some issues if RAND_MAX (the upper limit for rand) is defined to be smaller than your target range. In modern C++ it would be better to use the <random> header, as per the question Generate random numbers uniformly over an entire range.
Something like:
int main()
{
int randMax;
cin >> randMax;
for (int y = 0; y < 10; y++)
{
int x = rand() % randMax; // Range = [0, randMax)
cout << x+1 << endl; // Range = [1, randMax]
}
}
Oh, and do try to avoid goto (at least in my opinion). Here are two questions about it.