Finding min and max value in a random array - c++

Working on an assignment that requires me to put in some functions (finding max/min value, sum and average value of random numbers in an array), I've managed to complete all of them but for min value I'm getting a value of -2145379808. I'm not sure where I've messed up and I would appreciate the help.
Code so far:
#include <cstdlib>
#include <iostream>
#include <ctime>
using namespace std;
int main(int argc, char** argv) {
{
cout << "Enter array size " << endl;
}
float avg;
float sum;
int size;
cin >> size;
int array[size];
int max = array [0];
int min = array [0];
srand((unsigned)time(NULL));
for (int i = 1; i < size + 1; i++)
{
array[i] = 1+rand()%100 ;
sum += array[i];
cout << "number " << i << " = "<< array[i] << endl;
}
for (int x = 1; x < size; x++){
if (array[x] > max){
max = array[x];
}
if (array[x] < min){
min = array[x];
}
}
cout << "\nmax = " << max << endl;
cout << "\nmin = " << min << endl;
cout << "\nsum = "<< sum << endl;
cout << "\navg = " << sum / size << endl;
return 0;
}

Setting max and min to the uninitialised element of array is never going to end well. On this note, you also need to initialise sum. You may as well remove avg since you don't use it.
You need to set max and min to the first element of array once you know what it is. Crudely, you could set max to std::numeric_limits<int>::min() and min to std::numeric_limits<int>::max().
Note also that the bounds of array are array[0] to array[size - 1]. Therefore you need to revisit the indexing in your loops.
Then once you have it working, bin it, and use std::vector<int>, and things like minmax_element: http://en.cppreference.com/w/cpp/algorithm/minmax_element

The problem is in following lines:
float avg;
float sum;
...
int max = array [0];
int min = array [0];
Because at this point the value at array [0] are garbage value.
To correct your code change this line as following (also include climits header file). Also, change loops index accordingly:
float avg = 0;
float sum = 0;
...
int max = INT_MIN;
int min = INT_MAX;
Following is corrected code(some changes made for optimization). See it working here:
#include <cstdlib>
#include <iostream>
#include <ctime>
#include <climits>
using namespace std;
int main(int argc, char** argv) {
{
cout << "Enter array size " << endl;
}
float sum = 0;
int size;
cin >> size;
int array[size];
int max = INT_MIN;
int min = INT_MAX;
srand((unsigned)time(NULL));
for (int i = 0; i < size; i++)
{
array[i] = 1+rand()%100 ;
sum += array[i];
cout << "number " << i << " = "<< array[i] << endl;
if (array[i] > max){
max = array[i];
}
if (array[i] < min){
min = array[i];
}
}
cout << "\nmax = " << max << endl;
cout << "\nmin = " << min << endl;
cout << "\nsum = "<< sum << endl;
cout << "\navg = " << sum / size << endl;
return 0;
}

To insure your max and min are initialized correctly, C++ provides std::numeric_limits for all types. They each have max() and min() member functions to return the max and min value for the type. In any code you want to find a maximum and minimum, you want to first initialize your maximum to the minimum of the type and vice versa. That way any value will be larger than your min and smaller than your max.
You do that with std::numeric_limits similar to:
int min = std::numeric_limits<int>::max()
int max = std::numeric_limits<int>::min()
Let me know if you have more questions.

Related

why is my code not finding the index in my array?

I've put my code below. Basically, I find the lowest number of an element in the array, and I also want it to find the index of the lowest element. It finds the index with a fairly low amount of elements, but for some reason it sometimes just seems to return random numbers for the index, and I have no idea why.
You are increasing the variable index in each iteration of the for loop
index++;
And the variable min is redundant.
The for loop can look the following way
for (i = 1; i < size; i++)
{
if ( array[i] < array[index] )
{
index = i;
}
}
cout << "The smallest number is " << array[index] << " and is found at index " << index;
Pay attention to that there is standard algorithm std::min_element() that performs the same task.
For example
#include <iterator>
#include <algorithm>
//...
auto min = std::min_element( array, array + size );
std::cout << "The smallest number is " << *min << " and is found at index " << std::distance( array, min ) << '\n';
you need just add an index var on out of your loop and set it to zero . then evry time your max item has changed , your index changes too.
#include<iostream>
using namespace std;
int main()
{
int min;
int array[100];
int size;
int i;
int index = 0;
cin >> size;
for (i = 0; i < size; i++)
{
cin >> array[i];
}
min = array[0];
index =0
for (i = 0; i < size; i++)
{
if (min > array[i])
{
min = array[i];
index =i
}
i++;
}
cout << "The smallest number is " << min << " and is found at index " << index;
return 0;
}

Finding arithmetic mean between first min and last maximum element in an array

I have following problem to solve: given an array, I need to find the arithmetic mean between elements with indexes of first minimal and last maximum element (index boundaries are not inclusive).
For example, given {1, 5, 1, 9, 2, 7, 1, 3}, first minimal and last maximum elements are 1 and 9 respectively, their indexes are 0 and 3, so the answer would be an arithmetic mean of elements with indexes 1..2, i.e. arithmetic mean of 5 and 1, which is 3.
I know how to find the mean of the whole array but how to find the mean between the first min and last max element of the array?
#include <iostream>
using namespace std;
int main(){
setlocale(LC_ALL,"RUS");
cout << "Enter the array: ";
int k;
double Sum = 0;
double min = 0;
double max = 0;
const int n = 7;
double mass[8] = {0, 0, 0, 0, 0, 0, 0, 0};
for(k = 0; k <= n; k++){
cin >> mass[k];
}
for(int i = 0; i <= 7; i++){
if(mass[i] > max){
max = mass[i];
}
else if (mass[i] < min){
min = mass[i];
}
}
int i;
for(i = 0; i <= n; i++){
Sum = Sum + mass[i];
}
cout << Sum / 8;
return 0;
}
The answer should be 3.
I am assuming that you want a C++ program using C++ features. You current program is a C program that uses C++ I/O. Let me know if you want a C program that uses C features.
A C++ program means you should use std::vector but in case the assignment requires a C style array here is a version:
#include <iostream>
#include <algorithm>
#include <iterator>
#include <numeric>
int main() {
int size, *array;
std::cout << "How many elements? ";
std::cin >> size;
// create the array
array = new int[size];
if (array) {
// fill the array from the keyboard (could also use std::generate_n)
std::for_each(array, array+size, [index = 0](int& value) mutable {
std::cout << "Element " << ++index << "? ";
std::cin >> value;
});
// calculate the index of the max and min
auto minmax = std::minmax_element(array, array+size);
std::cout << "\nThe min " << *minmax.first << " is located at index " << std::distance(array, minmax.first);
std::cout << "\nThe max " << *minmax.second << " is located at index " << std::distance(array, minmax.second);
// calculate the average between the indexes
double average = std::accumulate(++minmax.first, minmax.second, 0.0, [count = 0](double average, int value) mutable {
std::cout << "\nAdding " << value << " to average";
return average + (value - average)/++count;
});
// print the result
std::cout << "\nAverage is " << average;
// delete the array
delete[] array;
}
}
And in case I am wrong and you are allowed to use std::vector here is a version:
#include <iostream>
#include <algorithm>
#include <iterator>
#include <numeric>
#include <vector>
int main() {
int size;
std::vector<int> array;
std::cout << "How many elements? ";
std::cin >> size;
// fill the array from the keyboard
std::generate_n(std::back_inserter(array), size, [index = 0, value = 0]() mutable {
std::cout << "Element " << ++index << "? ";
std::cin >> value;
return value;
});
// calculate the index of the max and min
auto minmax = std::minmax_element(array.begin(), array.end());
std::cout << "\nThe min " << *minmax.first << " is located at index " << std::distance(array.begin(), minmax.first);
std::cout << "\nThe max " << *minmax.second << " is located at index " << std::distance(array.begin(), minmax.second);
// calculate the average between the indexes
double average = std::accumulate(++minmax.first, minmax.second, 0.0, [count = 0](double average, int value) mutable {
std::cout << "\nAdding " << value << " to average";
return average + (value - average)/++count;
});
// print the result
std::cout << "\nAverage is " << average;
}
You need to think in terms of iterators, not values. Instead of recording the first minimal value, create an iterator that points the element one past it. Instead of recording the last maximal value, create an iterator that points to that value. You can then pass the range defined by these to iterators to std::accumulate to do the summation and then divide this by the std::distance of the same range to find the mean. But be aware that the number of elements between the min and max might be 0.
First, you need to find indexes.
Then loop through the array from first minimal to index of last maximum.
You can use the code below
#include <iostream>
using namespace std;
int main()
{
int array[] = { 1, 5, 2, 10, 2, 7, 1, 10};
int min = array[0];
int max = array[0];
int indexOfMin = 0;
int indexOfMax = 0;
int sum = 0;
float dist = 0;
float mean = 0;
int arrSize = sizeof(array)/sizeof(array[0]);
for (int i = 0; i < arrSize; i++){
if(array[i] >= max ){
max = array[i];
indexOfMax = i;
}
}
cout << "Max is at index [" << indexOfMax << "] : " << max << endl;
for (int i = 0; i < arrSize; i++){
if(array[i] == min){
continue;
}
if(array[i] < min){
min = array[i];
indexOfMin = i;
}
}
cout << "Min is at index [" << indexOfMin << "] : " << min << endl;
if(indexOfMin > indexOfMax){
indexOfMax++;
indexOfMin--;
for(int i = indexOfMax; i <= indexOfMin; i++){
sum += array[i];
}
dist = indexOfMin - indexOfMax + 1;
}else if(indexOfMin < indexOfMax){
indexOfMax--;
indexOfMin++;
for(int i = indexOfMin; i <= indexOfMax; i++){
sum += array[i];
}
dist = indexOfMax - indexOfMin + 1;
}
mean = sum/dist;
cout << "Sum: " << sum << " && dist: " << dist << endl;
cout << "Mean: " << mean << endl;
return 0;
}
Output:
Max is at index [7] : 10
Min is at index [0] : 1
Sum: 27 && dist: 6
Mean: 4.5
Output for int array[] = {1, 5, 1, 9, 2, 7, 1, 3} :
Max is at index [3] : 9
Min is at index [0] : 1
Sum: 6 && dist: 2
Mean: 3

C++ calculations not printing in proper format

I am working on a homework assignment and when I run my program my calculations are being displayed as -7.40477e+61. I am using visual studio as my IDE and when I check my code on an online checker it displays just fine. I am not sure why everything is being printed in that format. Any advice would be great!
#include <iostream>
#include <iomanip>
#include <string>
#include <ctime>
using namespace std;
int main()
{
double dArr[5];
long lArr[7] = { 100000, 134567, 123456, 9, -234567, -1, 123489 };
int iArr[3][5];
char sName[30] = "fjksdfjls fjklsfjs";
short cnt1, cnt2;
long double total = 0;
double average;
long highest;
srand((unsigned int)time(NULL));
for (int val : dArr) {
dArr[val] = rand() % 100000 + 1;
cout << dArr[val] << endl;
}
for (int count = 0; count < 5; count++) {
total += dArr[count];
average = total / 5;
}
cout << endl;
cout << "The total of the dArr array is " << total << endl;
cout << endl;
cout << "The average of the dArr array is " << average << endl;
cout << endl;
system("pause");
return 0;
}
The range-based for loop:
for (int val : dArr)
iterates val over the values of the collection dArr, not the indexes of that collection. So, when you attempt:
dArr[val] = rand() % 100000 + 1;
within said loop, it's unlikely to to give you the results you expect. Since dArr is local to main, it may have any values in it.
A better way would be to mirror your second loop, with something like:
for (int count = 0; count < 5; count++) {
dArr[val] = rand() % 100000 + 1;
cout << dArr[val] << endl;
}
Having said that, there appears to be no real reason why you're storing these numbers in an array at all (unless there's something about that in the problem statement that isn't shared in this question).
All you really need to do is keep the total, and the count so you can work out the mean. That could be as simple as (I've also changed the code to use Herb Sutter's AAA style, "almost always auto"):
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main() {
const auto count = 5U;
srand((unsigned int)time(NULL));
auto total = 0.0L;
for (auto index = 0U; index < count; ++index) {
const auto value = rand() % 100000 + 1;
cout << value << "\n";
total += value;
}
const auto average = total / count;
cout << "\nThe total of the dArr array is " << total << "\n";
cout << "The average of the dArr array is " << average << "\n\n";
return 0;
}

Why do I get a program crash for large values but not small values for my program?

Why do I get a program crash for large values but not small values for my program? If I input 1-3 the program does what it is supposed to but when I enter a number greater than that the program crashes and/or does not complete? Is it something to do with a pointer error or the way I've referenced something? I'm unsure so any help is appreciated. Thanks!
Code:
#include <iostream>
using namespace std;
void getData (int size, int *Arr){
cout << "\n\nEnter integer data one line at a time\n" << endl ;
for (int i=0; i < size; i++){
cin >> Arr[i];
}
}
void findMinAndMax(int array[], int size, int *min, int *max) {
int smallest = array[0];
int largest = array[0];
*min = smallest;
*max = largest;
for (int i = 1; i < size; i++)
{
if (array[i] > *max){
*max = array[i];
cout << "Max Value (loop): " << *max << endl;
}
if (array[i] < *min){
*min = array[i];
cout << "Min Value (loop): " << *max << endl;
}
}
// testing code
cout << "Min Value: " << *min << endl;
cout << "Max Value: " << *max << endl;
}
int *makeFrequency (int data[], int dSize, int *minDataValue, int *maxDataValue) {
cout << "Min Value Pre: " << *minDataValue << endl;// testing code
cout << "Max Value Pre: " << *maxDataValue << endl;// testing code
findMinAndMax(data, dSize, minDataValue, maxDataValue);
cout << "Min Value Post: " << *minDataValue << endl; // testing code
cout << "Max Value Post: " << *maxDataValue << endl;// testing code
int fSize = *minDataValue + *maxDataValue;
cout << "fSize: " << fSize << endl; // testing code
int *frequency;
frequency = new int [fSize];
// if frequency is 0, end
if (frequency == 0)
{
return 0;
}
// set all elements to 0 in array frequency
for (int i = 0; i <= fSize; i++) {
frequency[i] = 0;
}
for (int i = 0; i <= dSize; i++) {
int j = data[i] - (*minDataValue) + 1;
frequency[j] = frequency[j] + 1;
}
return frequency;
}
void makeHistogram (int *freq, int min, int max ){
cout << "Frequency Value HISTOGRAM: " << *freq << endl;
cout << "\n\n\n ----------- Histogram ----------------\n" << endl;
int size = min + max;
cout << "Size Value HISTOGRAM: " << size << endl;
for (int i = 0; i < size; i++){
if (freq[i] > 0) {
cout << "\n" << min + i - 1 << ": ";
for (int j = 0; j < freq[i]; j++) {
cout << '*';
}
}
}
cout << endl << endl;
}
int main() {
int dSize;
int *ArrayOfInts;
cout << "How many data values? ";
cin >> dSize;
ArrayOfInts = new int [dSize];
getData(dSize, ArrayOfInts);
int *frequency, min, max;
frequency = makeFrequency(ArrayOfInts, dSize, &min, &max);
if (frequency == 0) return -1;
cout << "Min Value MAIN: " << min << endl; // testing code
cout << "Max Value MAIN: " << max << endl; // testing code
cout << "Frequency Value MAIN: " << *frequency << endl;
makeHistogram(frequency, min, max);
delete [] frequency;
return 0;
}
One place where you have undefined behaviour which can cause crashes:
here you allocate fSize elements:
frequency = new int [fSize];
later you iterate it until fSize:
for (int i = 0; i <= fSize; i++) {
you should change to i < fSize, because there is no fSize element in your array. And the same problem with i <= dSize later on. Should be i < dSize.
btw. I dont see why only large values should cause crashes in your code, maybe this is just UB.
You're setting fSize incorrectly. It should be the difference between the maximum and minimum values, not the sum of them. Otherwise, if you have negative numbers in your list, the frequency array will be too small. And if absolute value of any of the negative numbers is larger than the highest number, fSize will be negative, which is not valid for the size of an array.
Then you need to add 1 to include both endpoints. So it should be:
int fSize = *maxDataValue - *minDataValue + 1;
Then, as the other answer pointed out, you need to fix your for loops. When the size of an array is N, the array indexes from from 0 to N-1. So it should be:
for (int i = 0; i < fSize; i++) {
using < as the loop test, not <=. If you try to write outside an array, you invoke undefined behavior, so anything can happen -- if you're lucky you get a crash, but that's not guaranteed.
You have a similar problem when you assign to frequency:
for (int i = 0; i <= dSize; i++) {
int j = data[i] - (*minDataValue) + 1;
frequency[j] = frequency[j] + 1;
}
There's no need to add 1 when subtracting *minDataValue, and doing so will cause you to go outside the array when data[i] is the maximum.

calculate average of array elements and display them

The problem is:
A Class of 40 students has received their grades for 5 exams. Implement a function that calculates the worst average grade and display the the IDs of all students having the worst average grade.‎
I already calculated the average but do not know how to calculate the WORST average ( as in the lowest average of the 40 students) and displaying the ID numbers that have this number.
This is what I have written so far:
#include<iostream>
#include <iomanip>
using namespace std;
const int MAX_NUM = 6;
int x[MAX_NUM];
int y[5];
int main()
{
float avg;
float total = 0;
for (int i = 0; i < MAX_NUM; i++)
{
cout << "Enter an ID number: " << endl;
cin >> x[i];
cout << "Enter 5 grades: " << endl;
for (int j = 0; j < 5; j++)
{
cin >> y[j];
while (y[j]>100)
{
cout << "Please enter a valid grade that is less than a 100: " << endl;
cin >> y[j];
}
total += y[j];
}
avg = total / 5;
cout << "ID: " << x[i] << endl;
cout << "Average: "<< avg << endl;
}
Something like this:
Note: I have added some important statements!
#include<iostream>
#include <iomanip>
using namespace std;
const int MAX_NUM = 6;
int x[MAX_NUM];
int y[5];
float AVG[MAX_NUM];
int worstIDCount = 0;
int main()
{
float avg, min = 1001;
float total = 0;
for (int i = 0; i < MAX_NUM; i++)
{
avg = 0;
total = 0;
cout << "Enter an ID number: " << endl;
cin >> x[i];
cout << "Enter 5 grades: " << endl;
for (int j = 0; j < 5; j++)
{
cin >> y[j];
while (y[j]>100)
{
cout << "Please enter a valid grade that is less than a 100: " << endl;
cin >> y[j];
}
total += y[j];
}
avg = total / 5;
AVG[i] = avg;
if(avg < min)
min = avg;
cout << "ID: " << x[i] << endl;
cout << "Average: "<< avg << endl;
}
for(int i = 0; i < MAX_NUM; i++)
{
if(AVG[i] == min)
cout << "Student with WORST Average: ID" << x[i] << endl;
}
};
So you want to store these averages in a std::vector<float>, std::sort it and get the lowest. Then go back and find the students that have that average.
working example
#include <iostream>
#include <vector>
#include <functional> // mem_fn
#include <algorithm> // sort, upper_bound
#include <iterator> // ostream_iterator
struct Student_average {
int student_id;
float average;
};
bool compare_student_averages(Student_average const &lhs,
Student_average const &rhs) {
return lhs.average < rhs.average;
}
int main() {
std::vector<Student_average> averages;
// collect the data and populate the averages vector
// ...
sort(begin(averages), end(averages), compare_student_averages);
std::cout << "The worst average is: " << averages.front().average << '\n';
auto end_of_worst_student_averages =
upper_bound(begin(averages), end(averages), averages.front(),
compare_student_averages);
std::cout << "The IDs of the students with the worst averages are:\n";
transform(begin(averages), end_of_worst_student_averages,
std::ostream_iterator<int>(std::cout, "\n"),
std::mem_fn(&Student_average::student_id));
}
Here is a more C++ way of doing this using std::accumulate and std::min_element (I removed the check for anything > 100, for brevity):
#include <iostream>
#include <algorithm>
#include <numeric>
using namespace std;
const int MAX_NUM = 6;
int x[MAX_NUM];
int y[5];
int main()
{
float avg[5];
float total = 0;
for (int i = 0; i < MAX_NUM; i++)
{
cin >> x[i]; // ID
for (int j = 0; j < 5; ++j)
cin >> y[j]; // grades
// compute the average for this student
avg[i] = std::accumulate(y, y + 5, 0) / 5.0F;
cout << "ID: " << x[i] << endl;
cout << "Average: "<< avg[i] << endl;
}
// compute the worst average
float* worst_average = std::min_element(avg, avg + MAX_NUM);
// get the position in the array where the worst is found
int position = std::distance(avg, worst_average);
// output results
cout << "This person has the worst average: " << x[position]
<<". The average is " << *worst_average << "\n";
}
Note that the averages are stored in an array. The way the average is computed for each person is to use std::accumulate to add up the y array values, and then divide by 5.0.
Since we now have the averages in an aray, we want to find the smallest item in the array. To do that, min_element is used to get us the position of where the element is stored.
The trick here is that min_element returns a pointer to the smallest item, so we need calculate how far this pointer is located from the beginning of the avg array. To do this, the std::distance function is used. This now gives us the position of the smallest item.
The rest of the code just outputs the results.
As you can see, the only loops involved were the input loops. The calculation of the average and the worst average were done using accumulate and min_element, respectively.