Outputting Max min and average from a randomized array? - c++

I was wondering if anyone can help me with something I was struggling all day with.
In the code below I dictated an array of randomized numbers from which I have to have pull out the max the min and the average. It all looks fine and good (such a compact software!) But I attain a weird output. I believe I have a finger on what the problem is (say I'm finding the max for the first number but the next number is smaller the software will think that's the biggest number even though integer 14 may be bigger) but I have no idea how to go about fixing this. The minimum value I have no idea why it's wrong it keeps saying it's zero and the average value stays anywhere from 10-19 which is impossible considering the range of randomized numbers goes from 1 to 1000. I was never taught how to organize random numbers in an array, so I just have no idea how to go about fixing this. Any help will be super awesome! I really struggled with this program and even scrapped it multiple times, if it's only a simple mistake I overlooked I would feel awfully embarrassed I'll post the code and an example output below.
Thanks for taking your time, I hope you have a wonderful day!
#include <cmath>
#include <iostream>
#include<cstdlib>
#include <ctime>
#include <time.h>
#include <iomanip>
using namespace std;
int main()
{
//Defining variables
//DEFINE SIZE
const int ARRAY_SIZE =20;
//Index variable
int i;
//For finding average
double sum=0;
double max_value;
double min_value;
//Keep all numbers sane
cout.precision(5);
srand((unsigned)time(0));
double main_array[ARRAY_SIZE];
//Header
cout << "Element number \t\t" << "Random Number\n\n" << endl;
//Assigning random values into array.
for (i=0; i< ARRAY_SIZE; i++)
{
max_value=0;
min_value=0;
//Randomizer
double ran = 0 + (rand()/((float)RAND_MAX/(1000-0)));
main_array[i] = ran;
cout << "\t" << i << "\t\t" << main_array[i] << endl;
//Find average
sum= (sum + main_array[i]);
sum= sum/(ARRAY_SIZE+1);
//Initalizing
for (int i = 0; i < ARRAY_SIZE; i++)
{
if ( min_value > ran)
min_value = main_array[i];
if (max_value < ran)
max_value = main_array[i];
}
}
cout <<"Average Value is: " << sum << endl;
cout <<"\nThe Minimum Value Is: " << min_value << endl;
cout <<"\nThe Maximum value Is: " << max_value << endl;
system ("pause");
return 0;
}
An output example would be
Element number Random Number
0 791.62
1 542.04
2 879.57
3 875.39
4 38.057
5 73.702
6 973.27
7 22.431
8 830.26
9 444.59
10 276.89
11 888.12
12 827.17
13 900.45
14 883.72
15 201.15
16 317.64
17 649.83
18 443.98
19 683
Average Value is: 33.603
The Minimum Value Is: 0
The Maximum value Is: 791.62
Press any key to continue . . .

Unless you must do otherwise, use std::min_element to find the minimum, std::max_element to find the maximum, and std::accumulate to find the sum.
If you absolutely must do this on your own, you usually want to initialize your minimum and maximum to the first element in the collection, then look for others that are smaller/larger:
int mininum = array[0];
int maximum = array[0];
for (int i=1; i<array_size; i++) {
if (array[i] < minimum)
minimum = array[i];
if (array[i] > maximum)
maximum = array[i];
}

Before you start looping, create a min, max, and total. Then when you are creating each element of the array, also check whether it is less than the min or more than the max. Also add that number to your total. At the end, outside the loop, divide the total by the number of elements to get your average.
You definitely shouldn't be iterating through the whole array each time you add an element, and you shouldn't be resetting your min and max each time through the loop. You also shouldn't set your min to 0 if all your numbers are going to be more than 0, because it will never be updated.

Related

C++ 2 dice rolling 10 million times BEGINNER

I am trying to create a program that will roll 2 dice 10 million times, and output how many times each number is rolled. Along with this, I am tasked with creating a histogram (*=2000) for the outputs.
Here is what I have so far.
/*
Creating a program that counts outcomes of two dice rolls, then show a
histogram of the outcomes.
Section 1 : Simulate ten million times rolls of two dice, while counting
outcomes. (Hint: Use an array of size 13.)
Section 2 : Show the outcome, the numbers of outcomes, and the histogram
(one * designates 20000). Your output must align properly.
*/
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;
int main()
{
int i, j, ary[13] = {};
cout << "Please enter the random number seed.";
cin >> j;
srand(j);
for (i = 0; i < 10000000; i++)
ary[die() + die()]++;
for (i = 2; i <= 12; i++)
{
cout << setw(3) << i << " : " << setw(6) << ary[i] << " : ";
for (j = 0; j < ary[i]; j += 2000)
cout << "*";
cout << endl;
}
return 0;
}
EXAMPLE OUTPUT: https://imgur.com/a/tETCj4O
I know I need to do something with rand() % 6 + 1; in the beginning of the program. I feel like I am close to being complete but missing key points! I also realize I have not defnied die() in my ary[]
I recommend creating random seeds from high precision timers such as std::chrono::high_resolution_clock. Then they are not dependent on the user and are actually random. Create the seed always before calling std::rand.
#include <chrono>
auto time = std::chrono::high_resolution_clock::now();
auto seed = std::chrono::duration_cast<std::chrono::milliseconds>(time);
std::srand(seed)
Millisecond precision makes the seed usually unique enough but if the seed is required close to 1000 times a second then i recommend using nanosecond or microsecond precision to be really random.
Best would be to create a function that creates the random seed using high precision timer and the random value and finally makes sure the return value is between 0 and 5 (for 6 sided dice).

data streaming in c++

I have a program that can generate a random integer every 1/10 second.
Here is the code:
int main()
{
ofstream myfile;
int max;
cout << "Max number: ";
cin >> max;
for (int i = 0; i < max; ++i)
{
myfile.open("test.txt",fstream::app);
myfile << random_int() << "\n";
myfile.close();
this_thread::sleep_for(chrono::milliseconds(100));
}
return 0;
}
int random_int()
{
return rand() % 10;
}
Now the question is, I need to write a program that calculate then output the average in the same rate. If the output of the number generator is:
1
2
3
4
5
The output of the average calculator should be
1
1
2
2
3
Every 1/10 second the program will output a number.
Note: The max number could be from 0 to couple millions. Calculating the average by adding all previous number during the time interval won't be ideal.
I am a sophomore student and a research assistant in a university. This is a simplified version of a problem that I encounter currently. Any suggestion will be greatly appreciated.
Update: Thanks for the help from Fei Xiang and oklar. Yes, remember the previous sum is the only way to make the calculation in time. However, since the random generator output file is changing constantly and the new output is appended to the old outputs, I am not sure how to get the most current data efficiently.
You don't need to calculate all the numbers that has been added each time, you only need to add the last one to a sum variable and divide by the amount of generated numbers.
Say you have:
1
2
3
4
5
Sum variable is 15. If you divide by the amount of numbers which is 5, you'll get the expected output of 3. Continuing, add the number 9 for instance to the sum variable and divide by the amount of generated numbers 6, you'll end up with an average of 4.
The i in your for loop can be used as a counter for the amount of generated numbers. Pseudo code:
sum += randomInt();
avg = sum/i;
EDIT:
I see that you are opening and closing the file each time in the for loop in your post. This can be done outside the loop, which will speed things up. If I understand you correctly, your mission is to generate a random number then calculate the average from the previous numbers and finally append it to the text file? If so, you're on point.
int i_random;
int avg;
int sum = 0;
myfile.open("avg.txt",fstream::app);
for (int i = 1; i < max + 1; ++i)
{
i_random = random_int();
sum += i_random;
avg = sum/i;
myfile << avg << "\n";
this_thread::sleep_for(chrono::milliseconds(100));
}
myfile.close();
See http://www.cplusplus.com/doc/tutorial/files/ for other operators. Check out cppreference for seek and tell if you want to skip to a position in the file.

C++: using for loop to allow user input of numbers into array

I'm new to the community and to coding as well. Right now I'm taking Intro to Computer Science at my CC and we're learning C++. Anyways, I have to create a program which asks the user for a number, which will be the size indicator of the array new_array. The program then asks the user to input the numbers one by one and afterwards, outputs them in reverse.
#include
using namespace std;
int main()
{
cout << "How many numbers?\n";
int numbers; // holds amount of numbers to be entered into array
cin >> numbers;
int new_array[numbers];
for(int counter = 0; counter < numbers; counter++)
{
cout << "Enter number " << counter << endl;
cin >> new_array[counter];
}
cout << "You entered: " << endl;
for(int i = numbers; i >= 0 ; i-- )
{
cout << new_array[i] << endl;
}
return 0;
}
I understand how to do this and for the most part, my program worked. It outputs the numbers entered in reverse just fine, but before it does so, it outputs large, strange numbers. For example, if the user enters 5 as the amount of numbers to be entered, and then enters 1, 2, 3, 4 and 6 as the 5 numbers respectively, the program outputs the number 4669476 first and then outputs the numbers in the array in reverse. Can anyone explain to me what I did wrong and how I could fix this? Thank you in advanced!
PS be gentle! I'm a newbie at this
This loop reads out of bounds:
for(int i = numbers; i >= 0 ; i-- )
{
If you follow i through in your head you will see that you output entries numbers through to 0, when in fact you should output entries numbers-1 through to 0.
An alternative patterns is:
for( int i = numbers; i--; )
Or you can use the fabled --> operator.
It would be possible to "simply" start from numbers - 1, however the loop pattern you have used would not work for an unsigned counter (because they are always >= 0). IMHO it is a good idea to use a pattern which works for all types; then you are less likely to make a mistake in future.
In your display for loop, you started from i = numbers which is out of the array's range. Since the array starts from 0 till size - 1, then you need to start from i = numbers - 1 all the way to >=0.
Because you start from array[numbers] which is not defined.
array[0], array[1], ... array[numbers-1] are defined.
In C arrays are stored from 0 instead of 1. So the last number is stored in array[4]
So when you're writing it out you should start an numbers - 1 instead of just numbers.
Because you are starting the index from out of range giving you garbage value.
your code should look some thing like this
for(int i = numbers-1; i >= 0 ; i-- )
{
cout << new_array[i] << endl;
}

Finding the closest number of array to another given number

I have this program to write that I have a array of 11 numbers entered from me. Then I need to find the avarage sum of those numbers, and then im asked to find the closest number of this array to the avarage sum, and then the most distant element of the array to the avarage sum again. SO far I manage to write a program to create this array and find the avarage sum. I asssume there is something to do with abs function of cmath libary , but so far I only fail to make it.
#include <iostream>
using namespace std;
int main() {
unsigned const int size = 11;
float number[size];
for (unsigned i = 0; i<size; i++) {
cout << "Please enter value for number "
<< i + 1 << ":";
cin >> number[i];
}
for (unsigned i = 0; i<size; i++) {
cout << "Number " << i + 1 << " is : "
<< number[i] << endl;
}
unsigned int sum = 0;
for (unsigned i = 0; i<size; i++) {
sum += number[i];
}
What is the problem? You are not asking a question, just making a statement... It does seem that you have not posted the whole code..
In c++ usually to use "abs" you should use fabs from the "math.h" library!
You will be okay with the compare operators.
Just traverse your array in a loop and calculate the difference between your compare value and the current value on your array. Initiate a temporary variable that keeps the array entry that created the smallest difference.
Every time a difference that is smaller than the current one comes up replace the value in your temporary variable.
So you replace under the following condition: If |number[i] - average_value| < |tmp_closest_val -average_val| Then tmp_closest_val = number[i] EndIf.
I hope you get the concept from that rough draft.

maximum value for a specific example (Collatz function)

With the help of some people on here I managed to find the stopping values for a range of initial values 1 to 1000 in the Collatz function. Collatz function
(My mistake was sorted by using a new variable say s instead of c in the for loop and then letting c=s).
I am now trying to produce code to keep track of the maximum stopping value (count) for these initial values (1 to 1000) and then output it at the end. Could anyone give me some pointers if they know how to do this?
Thanks.
Define a maximum of zero before running the loop the first time. Then check if your stop value is greater than the current maximum value: If so set the current maximum to the current stop. Repeat this every time you found a stop value.
#include <iostream>
using namespace std;
int main()
{
long max = 0;
for(long c=2, c<=1000; c++) // define stopping value as 0 for c=1 elsewhere
{
long count=0;
while (c!=1)
{
if((c%2)==0)
{
c/=2;
}
else
{
c=3*c+1;
}
count ++;
}
if ( count > max ) max = count;
cout << "The stopping value for " << c << " is " << count << endl;
}
cout << "The max stopping value is " << max << endl;
return 0;
}