Find the smallest value in a vector - c++

I am pretty new when it comes to programming with STL and I thought I was getting the hang of it. But I am a little perplexed about this one bit. My goal is to take in 5 values, then print out my values, print the highest value among them, print the average, and print the lowest among them ( my problem ). It seems that my variable "low" is given the value of 0 and I do not know why this is. I have tested to see if my values are being read in and to my knowledge, they are. So if anyone could please enlighten me to why I cannot seem to get the proper lowest value, I would greatly appreciate it. Thank you for your time.
vector<double> vecList;
int x = 0;
double high = 0;
double low = 0;
double sum = 0;
cout << "Enter Integer Values, then press Ctrl(z) to Quit:" << endl;
for (int i=0; i < 5; i++)
{
cin >> x;
sum = sum + x;
vecList.push_back(x);
}
vector<double>::iterator intVecIter;
cout <<"List contains: ";
for (intVecIter = vecList.begin(); intVecIter != vecList.end(); ++intVecIter)
cout << *intVecIter << " ";
for (int i=0; i < 5; i++)
{
if(vecList[i] > high)
{
high = vecList[i];
}
// prints out "0"
if(low > vecList[i])
{
low = vecList[i];
}
}
cout << endl << "Largest: "<< fixed << setprecision(2) << high << endl;
cout << "Smallest: "<< fixed << setprecision(2) << low << endl;
cout << "Average: " << fixed << setprecision(2)<< (sum/5);
return 0;

Since you are trying to learn STL, take a look at the algorithms library and it has some helper functions which will give the min, max and sum (accumulate is the actual function name) for a given range.

you need to initalize low to a big value not 0, otherwise this
if(low > vecList[i])
is never true

Related

Finding the minumum value out of user inputs in C++

My problem is finding the minimum value out of user defined number of inputs. Everything so far works just fine, except that. Every time I try and rearrange some code or try a new method, I keep getting the same output on the screen:
Sum of numbers entered is: 145.4
Average of numbers entered is: 24.2333
The Highest number entered was: 45
The Lowest number entered was: 6.95283e-310
I get this every single time, regardless of what is entered, or what different suggestion I try:
The Lowest number entered was: 6.95283e-310
I am aware of the use and implementation of Arrays. However, the assignment I'm doing hasn't even covered arrays yet. That is some number of chapters later. Please don't suggest arrays...
I've looked here:
Finding Maximum and Minimum values in c++ by user input
Didn't work
http://www.cplusplus.com/forum/beginner/38799/
Didn't work
changing the values of max/min didn't work either
#include <iostream>
using namespace std;
int main()
{
double number, numberitems, sum = 0, average, max, min;
cout << "Enter number of items: \n";
cin >> numberitems;
//Make sure user can not enter negatives
if ( numberitems < 0 ) {
//no request to perform sum
std::cout << "I said not to enter a negative number... '\n";
std::cin.clear(); //clear bad input flag
return 1;
}
//Get the user's values
for (int i = 0; i < numberitems; i++)
{
std::cout << "Enter any NON-negative number: ";
std::cin >> number;
std::cout << '\n';
//Maximum value entered
if (number > max) {
max = number;
}
//minimum value entered
if (number < min) {
min = number;
}
//Make sure user can not enter negatives
if ( number < 0 ) {
//no request to perform sum
std::cout << "I said not to enter a negative number... '\n";
std::cin.clear(); //clear bad input flag
return 1;
}
//Sum of all the numbers
sum = sum + number;
//Average of all the numbers
average = sum / numberitems;
}
std::cout << endl;
std::cout << endl;
std::cout << "Sum of numbers entered is: " << sum << '\n';
std::cout << "Average of numbers entered is: " << average <<'\n';
std::cout << "The Highest number entered was: " << max <<'\n';
std::cout << "The Lowest number entered was: " << min <<'\n';
return 0;
}
Made a temporary fix :3
double min = 99999999999999999999999999999999999999999999999;
I'm very new to this.
Updated
After reading more comments I saw I was missing <cfloat>. Using #include <cfloat> NOW everyone's suggestions above work. However, <cfloat> was not covered in class, at all. So I'm not sure if that is usable here?
#include <iostream>
#include <cfloat>
using namespace std;
int main()
{
int numberitems;
double number, sum = 0, average;
double max = 0;
double min = DBL_MAX;
cout << "Enter number of items: \n";
cin >> numberitems;
//Make sure user can not enter negatives
if ( numberitems < 0 ) {
//no request to perform sum
std::cout << "I said not to enter a negative number... '\n";
std::cin.clear(); //clear bad input flag
return 1;
}
//Get the user's values
for (int i = 0; i < numberitems; i++)
{
std::cout << "Enter any NON-negative number: ";
std::cin >> number;
std::cout << '\n';
//Maximum value entered
if (number >= max) {
max = number;
}
//minimum value entered
if (number <= min) {
min = number;
}
//Make sure user can not enter negatives
if ( number < 0 ) {
std::cout << "I said not to enter a negative number...'\n";
std::cin.clear(); //clear bad input flag
return 1;
}
//Sum of all the numbers
sum = sum + number;
//Average of all the numbers
average = sum / numberitems;
}
//Print the results
// some cosmetic...
std::cout << endl;
std::cout << endl;
std::cout << "\n=================REPORT====================\n";
std::cout << '\n';
std::cout << "\tYour Totals\tValues\n";
std::cout << "\t-----------\t------\n";
std::cout << "\t Sum: " << sum << '\n';
std::cout << "\t Average: " << average <<'\n';
std::cout << "\t Highest: " << max <<'\n';
std::cout << "\t Lowest: " << min <<'\n';
return 0;
}
Again, <cfloat> works fine, but I'm not sure if I'm allowed to use it. What other ways around this are there?
The question already got good answers - shortly: min and max are uninitialized.
However
Above is very specific.
Of course it helps in this specific case but I feel a broader advise that would work here and in many other cases is needed.
Add printouts
Adding debug printouts to your code ("debugging without a debugger") is always helpful in such cases.
For example adding the following in your example may help:
//Get the user's values
for (int i = 0; i < numberitems; i++)
{
std::cout << "Enter any NON-negative number: ";
std::cin >> number;
std::cout << '\n';
//Maximum value entered
if (number > max) {
// debug - (remove before submission)
std::cout << "number is the new max! number = " << number
<< ", max = " << max << std::endl;
// end of debug
max = number;
}
//minimum value entered
if (number < min) {
// (debug - remove before submission)
std::cout << "number is the new min! number = " << number
<< ", min = " << min << std::endl;
// end of debug
min = number;
}
When calculating minimum and maximum, you should initialize your variables to a default value. For minimum, it's the maximal possible value; for maximum - the minimal possible one.
double max, min; // BUG - not initialized
#include <float.h> // or <cfloat>
...
double max = 0; // CORRECT - initialized
double min = DBL_MAX; // CORRECT - initialized
For maximum, the initialization is usually -DBL_MAX (note: not DBL_MIN), but 0 is good enough in this case, when no negative values exist.
You need to set an initial value for min and max. For min, I'd suggest using an initial value of DBL_MAX, which is defined in the header cfloat.

What is happening with vector array here?

I'm solving the Traveling Salesman Problem via an ACO implementation in C++. However, I found out that the program I've built so far gives a segmentation fault.
(Note: I've limited the algorithm to only do one iteration of the colony for debugging purposes).
First off, I have a total of 52 cities taken from a file, and I distribute the ants so that every city has the same number of ants starting from it.
To store the distances between every pair of cities, I'm using a vector of vectors of doubles called Map (a square matrix). However, half-way during the execution it looks like these vectors are deleted. In this instance, it happens when calculating the path for the ant number 55. I've added a section of code just to highlight exactly where it crashes:
//DEBUGGING SECTION
cout << "Size Roulette: " << Roulette.size() << endl;
cout << "Size Remain: " << RemainingCities.size() << endl;
cout << "Size Map: " << Map.size() << " x " << Map[0].size() << endl;
int k = 0;
cout << "Test: Map access: " << endl;
for(int i = 0; i < Map.size(); ++i) // HERE IT CRASHES AT ANT NUMBER 55
cout << Map[0][i] << " ";
cout << endl;
cout << "Test: Operation: " << Map[Colony[ant_i][city_i-1]][RemainingCities[k]] << endl;
Roulette[k] = pow((MAX_DIST - Map[Colony[ant_i][city_i-1]][RemainingCities[k]]), heur_coef) + pow((pheromones[Colony[ant_i][city_i-1]][RemainingCities[k]]), pher_coef);
//END OF DEBUGGING SECTION
There, the function Map[0].size() normally returns 52 (just like Map.size(), as it's supposed to be a square matrix), but at the crashing iteration it returns what looks like a memory address, and the moment I try to access any element, a segmentation fault occurs.
I have checked that the memory access is always correct, and I can access any other variable without issue except Map until that 55th ant.
I've tried different seeds for the roulette method, but it always crashes at the same place.
I have also varied the number of ants of the colony. If it's just one ant per city, the program executes without issue, but for any higher amount the program always crashes at the 55th ant.
You can download the full cpp file and the reading .tsp file from github:
https://github.com/yitosmash/ACO
In any case, I'll leave the full function here:
void ACO(const vector<City>& cities, const vector<vector<double>>& Map, int max_it, int num_ants, double decay, double heur_coef, double pher_coef, double pher_coef_elit)
{
srand(30);
//Initialise colony of ants (each ant is a vector of city indices)
vector<vector<int>> Colony(num_ants, vector<int>(cities.size(), 0));
//Initialise pheromone matrix
vector<vector<double>> pheromones(cities.size(), vector<double>(cities.size(), 0));
//Initialise costs vector(for etilist expansion)
vector<double> costs(cities.size(), 0);
//Auxiliar vector of indices
vector<int> cityIndices(cities.size());
for (int i = 0; i < cities.size(); ++i)
cityIndices[i] = i;
//Longest distance from Map, used for heuristic values.
vector<double> longests(cities.size(), 0);
for(int i = 0; i < cities.size(); ++i)
longests[i] = *(max_element(Map[i].begin(), Map[i].end()));
const double MAX_DIST = *(max_element(longests.begin(), longests.end()));
longests.clear();
int i=0;
while(i<max_it)
{
for(int ant_i = 0; ant_i < num_ants; ++ant_i)
{
cout << "Ant: " << ant_i << endl;
//City for ant_i to start at; each ant is assigned a determined starting city
int starting_city = (int) ((float)ant_i/num_ants*cities.size());
//cout << starting_city << endl;
Colony[ant_i][0] = starting_city;
//Get a vector with the cities left to visit
vector<int> RemainingCities = cityIndices;
//Remove starting city from remaining cities
RemainingCities.erase(RemainingCities.begin() + starting_city);
//Create path for ant_i
for(int city_i = 1; city_i < Colony[ant_i].size(); ++city_i)
{
cout << "Calculating city number: " << city_i << endl;
//Create roulette for next city selection
vector<double> Roulette(RemainingCities.size(), 0);
double total = 0;
//DEBUGGING SECTION
cout << "Size Roulette: " << Roulette.size() << endl;
cout << "Size Remain: " << RemainingCities.size() << endl;
cout << "Size Map: " << Map.size() << " x " << Map[0].size() << endl;
int k = 0;
cout << "Test: Map access: " << endl;
for(int i = 0; i < Map.size(); ++i) // HERE IT CRASHES AT ANT NUMBER 55
cout << Map[0][i] << " ";
cout << endl;
cout << "Test: Operation: " << Map[Colony[ant_i][city_i-1]][RemainingCities[k]] << endl;
Roulette[k] = pow((MAX_DIST - Map[Colony[ant_i][city_i-1]][RemainingCities[k]]), heur_coef) + pow((pheromones[Colony[ant_i][city_i-1]][RemainingCities[k]]), pher_coef);
//END OF DEBUGGING SECTION
for(int j = 0; j < RemainingCities.size(); ++j)
{
//Heuristic value is MAX_DIST - current edge.
Roulette[j] = pow((MAX_DIST - Map[Colony[ant_i][city_i-1]][RemainingCities[j]]), heur_coef) + pow((pheromones[Colony[ant_i][city_i-1]][RemainingCities[j]]), pher_coef);
total += Roulette[j];
}
cout << endl;
//Transform roulette into stacked probabilities
Roulette[0] = Roulette[0]/total;
for(int j = 1; j < Roulette.size(); ++j)
Roulette[j] = Roulette[j-1] + Roulette[j] / total;
//Select a city from Roulette
int chosen = 0;
double r = (double) rand()/RAND_MAX;
while(Roulette[chosen] < r)
chosen++;
//Add chosen city to
Colony[ant_i][city_i] = RemainingCities[chosen];
RemainingCities.erase(RemainingCities.begin() + chosen);
}
cout << endl;
//Save cost of ant_i, for elitist expansion
costs[ant_i] = pathCost(Colony[ant_i], Map);
}
i++;
}
}
That part is very suspicious :
for(int i = 0; i < Map.size(); ++i) // HERE IT CRASHES AT ANT NUMBER 55
cout << Map[0][i] << " ";
because i is the size of the map but you use it as an index in a probable string / vector, so you probably go out of the string/vector with an undefined behavior
probably you want
for(int i = 0; i < Map.size(); ++i)
cout << Map[i] << " ";
or
for(int i = 0; i < Map[0].size(); ++i)
cout << Map[0][i] << " ";
As I said in a remark at a moment RemainingCities[0] values -163172699 first in
cout << "Test: Operation: " << Map.at(Colony.at(ant_i).at(city_i-1)).at(RemainingCities.at(k)) << endl;
so is not a valid index in Map, but there is visible reason to have that looking at the code, so the reason is a probable write out of a vector destructing your memory elements.
To detect where I replaced all the [...] by .at(...) and the first error I have is in ACO at the line
costs.at(ant_i) = pathCost(Colony.at(ant_i), Map);
where ant_i values 52 while costs has 52 entries and Colony 260, so the error concerns costs
note that ant_i is set by the loop
for(int ant_i = 0; ant_i < num_ants; ++ant_i)
and in that case num_ants value 260 so much more than the size of costs which is defined as
vector<double> costs(cities.size(), 0);
but cost is just allocated and set but never read, so its goal is just to destruct the memory.
If I remove the two lines concerning it I do not have anymore an error and the program ends normally, there is no exception in a .at(...) and valgrind detect no error too.

Bjarne Stroustrup's P:PP Chapter 4 Drill

I've just started learning C++ and I'm working by myself through Bjarne Stroustup's P:P&P.
I am on the Chapter 4 drill.
The problem I am having seems to lie within the order of the program. If I add another closing curly brace right before the vector to close the while-statement, I get the right output for max_val and min_val. However by adding that brace, the double named sum remains at zero even though I want sum to increment by the double named number.
If I compile the program as it is written now (without the addition of the extra curly braces), I get the wrong output for min_val and max_val but the proper output for sum.
Also, as you can see at the bottom of the program, the line:
cout << " values were entered." << '\n'; is not complete. I wanted to print out the number of total values entered but left it incomplete due to frustration and need of help. I am very new to programming and any constructive criticism, no matter how harsh, would be appreciated.
#include "std_lib_facilities.h"
int main()
{
double value = 0;
double max_val = 0;
double min_val = 0;
string unit =" ";
double sum = 0;
cout << "Enter some numbers, followed by a unit of distance (m, cm, ft, inch):" << '\n';
while (cin >> value >> unit){
//determines entered value as max/min/both/neither
if (min_val == 0 && value > max_val){ // first number entered is both largest and smallest
max_val = value;
min_val = value;
cout << value << " metres is both the smallest and largest so far" << '\n';
}
else if (value < min_val){// smallest number min_val = value;
cout << min_val << " metres is the smallest so far." << '\n';
}
else if (value > max_val){// largest number max_val = value;
cout << max_val << " metres is the largest so far." << '\n';
}
else { // number between smallest and largest
cout << value << " metres is neither the smallest or largest." << '\n'; }
//convert entered unit to metres
if (unit == "m"){
value = value;
}
else if (unit == "cm"){//converts cm to metres
value = value/100;
}
else if (unit == "ft"){//converts ft to metres
value = value/3.28084;
}
else if (unit == "inch"){//converts inch to metres
value = value/39.3701;
}
else{
cout << "I dont know the unit " << unit << ".";
}
vector <double> numbers; //reads input into vector
double number = 0;
while (cin >> number) numbers.push_back(number);
for (double number: numbers) sum += number;
cout << "The largest value entered was: " << max_val << "." << '\n';
cout << "The smallest value entered was: " << min_val << "." << '\n';
cout << "The sum of the numbers entered is: " << sum << "metres" <<'\n';
cout << " values were entered." << '\n';
keep_window_open("~");
return 0;
}
Here is a small insight regarding the input loop, finding min_value, max_value and sum:
#include "../../std_lib_facilities.h"
int main(){
// vector holding the input values
vector<double> inputValues;
// vector-input variable
double temp = 0;
// variable holding the sum of the input
double sum = 0;
// variables holding the minimum and maximum input value
double minVal = 100000; // note the initialization values
double maxVal = -100000;
vector<string>units;
string unit;
// prompt message; value input
cout << "Enter the first value: ";
while (cin >> temp >> unit) {
cout << "Enter the next value: ";
inputValues.push_back(temp);
units.push_back(unit);
}
// conversion...
for (int i = 0; i < inputValues.size(); ++i){
if (inputValues[i] > maxVal){ maxVal = inputValues[i]; }
if (inputValues[i] < minVal){ minVal = inputValues[i]; }
sum += inputValues[i];
}
// print result
cout << "Minimum temperature = " << minVal << endl;
cout << "Maximum temperature = " << maxVal << endl;
cout << "Average temperature = " << sum/inputValues.size() << endl;
return 0;
}
For the conversion you can use a second container, e.g. vector to store the units and then create a loop using the same index for both values and units, with a if, else if block for each unit conversion:
vector<string> units;
for(int i = 0 ; i < inputValues.size(); ++i){
if(units[i] == "cm") inputValue[i] = inputValue[i] / 100.;
else if(units[i] == "...") inputValue[i] =...;
// ...
}
Note:
the input loop needs improvement, e.g. termination condition, think about termination keyword with do-while loop, handling of wrong input types, cin.clear(), etc.

Function not returning the highest and lowest values entered into the array

This function is not accurately returning the highest and lowest values entered into the array. I'm not sure what I code I entered for the program to do this. This program needs to return the average of all of the elements entered into the array (the average part works fine) as well as find the highest and lowest values among all of the values entered into the array. Please help!
#include <iostream>
using namespace std;
float temptotal = 0;
float averagetemp = 0;
float temperatures[50];
float average(int);
void highest(int);
void lowest(int);
int main()
{
int days = 0;
cout << "Enter the number of days: ";
cin >> days;
if (days > 50)
{
cout << "You may only enter temperatures for 50 days." << endl;
return 0;
}
average(days);
highest(days);
lowest(days);
}
float average(int days)
{
for (int i = 1; i <= days; i++)
{
cout << "Enter the temperature for day number " << i << ": ";
cin >> temperatures[i];
temptotal += temperatures[i];
}
averagetemp = temptotal / days;
cout << "The average temperature is: " << averagetemp << endl;
return averagetemp;
}
void highest(int days)
{
int count;
int highest;
highest = temperatures[50];
for (count = 1; count < days; count++)
{
if (temperatures[count] > highest)
highest = temperatures[count];
cout << "The highest temperature is: " << highest << endl;
}
}
void lowest(int days)
{
int count;
int lowest;
lowest = temperatures[50];
for (count = 1; count < days; count++)
{
if (temperatures[count] < lowest)
lowest = temperatures[count];
cout << "The lowest temperature is: " << lowest << endl;
}
}
This function
float average(int days)
{
for (int i = 1; i <= days; i++)
{
cout << "Enter the temperature for day number " << i << ": ";
cin >> temperatures[i];
temptotal += temperatures[i];
//...
is already wrong because element temperatures[0] will not be uninitialized. You have to write
float average(int days)
{
for (int i = 1; i <= days; i++)
{
cout << "Enter the temperature for day number " << i << ": ";
cin >> temperatures[i-1];
temptotal += temperatures[i-1];
//...
Or
float average(int days)
{
for (int i = 0; i < days; i++)
{
cout << "Enter the temperature for day number " << i + 1 << ": ";
cin >> temperatures[i];
temptotal += temperatures[i];
//...
Functions highest and lowest are also wrong. For example array temperatures has no element with index 50. Moreover the user can enter number of days less than 50. So this statement
highest = temperatures[50];
is wrong.
The functions can be written like this function definition
void highest( int days )
{
int highest = temperatures[0];
for ( int count = 1; count < days; count++ )
{
if ( highest < temperatures[count] ) highest = temperatures[count];
}
cout << "The highest temperature is: " << highest << endl;
}
Take into acccount that there are standard algorithms std::max_element, std::min_element, std::minmax_element declared in header <algorithm> that can be used instead of your functions.
For example function highest can be defined with using standard algorithm std::max_element the following way
#include <algorithm>
//...
void highest( int days )
{
cout << "The highest temperature is: "
<< *std::max_element( temperatures, temperatures + days )
<< endl;
}
Array indices start with a 0
Place the cout statements outside the for loop.
Arrays are indexed from 0 to n-1, where n is the total number of entries in the array. You started the count at 1 in your loop when you should start at 0. If the user entered 50 values, you would have had an out-of-bounds access.
The correction should be:
for (int i = 0; i < days; i++)
Then in your output statement, it should be:
cout << "Enter the temperature for day number " << i+1 << ": ";
The other issue is your highest function. The issue are a few things:
You declared the local variable highest as an int. It should be a float to match the type used in the temperature array.
You should set highest to a very small value, smaller than any you would expect. Or better yet, set it to the first temperature entry before the loop, and start the loop from the second entry.
You named your local variable highest, but your function name is also highest. This will lead to confusion when someone else looks at your code.
If you're interested in another solution, the following computes the highest:
#include <algorithm>
//...
void highest(int days)
{
float theHighest = *std::max_element(temperatures, temperatures + days);
cout << "The highest temperature is: " << theHighest << endl;
}
A little better version from the function 'highest':
void highest(int days)
{
if (days < 1)
{
cout << "No temperatures" << endl;
}
double highest = temperatures[0];
for (int count = 1; count < days; count++)
{
if (temperatures[count] > highest)
{
highest = temperatures[count];
}
}
cout << "The highest temperature is: " << temperatures[highest_index] << endl;
}
All arrays in C++ starting with index 0. In this implementation this point is considered by using the first element (index 0) as thie first highest value. After that the loop has only to deal with the rest, begining at index 1.
The variable 'highest' must be from the type double. Otherwise you may get wrong results, because the highest is a little lower than the real highest due to generaly rounding down (double to int). The next comparison may be assigned even if it is a little lower.
Array indices start with 0 but your loops start at 1. For your loop over days, for instance, this will iterate over the full range:
for (int i = 0; i < days; i++)

Entering 20 numbers into an array with no duplicates

int main()
{
int theArray [20] = {0};
int userInput = 0;
int populateCount = 0;
cout << "Enter 20 integers between 10 and 100 inclusive. " << endl;
while (populateCount < 20)
{
cin >> userInput;
theArray[populateCount] = {userInput};
if (userInput<10||userInput>100)
{
cout << "That is not a legal input. " << endl;
populateCount - 2;
}
else
{
populateCount++;
}
}
cout << "\n";
for (int i = 0; i < 20; i++)
{
cout << theArray[i] << endl;
}
}
I've got the baseline of my code done. The user enters twenty numbers and they're added to the array. If it's less than 10 or greater than 100 it's not a legal input, I subtract from the count, and they're allowed to go again. Then after the user finishes plugging in numbers it prints the array. However, I've been trying different if statements inside the array to eliminate duplicates, such as (if theArray[i] == theArray[i+1] then [i+1] = 0) I suppose that could work if I incorporated a sort to get all the 0's at the end, but is there a more efficient way to do this?
Before I go to the answer I suggest we clean it up slightly to make the problem more clear and remove other confusion.
Misconception
The statement populateCount - 2 has no effect.. instead you are simply not incrementing populateCount which is why the loop doesn't advance.
I would suggest something of this format within the loop. It puts the 'happy' path first, which will also make for some clearer ways to handle the second part.
if (userInput >= 10 && userInput <= 100 ) {
theArray[populateCount++] = userInput;
}
else {
std::cout << userInput << " is not legal input, must enter value "
<< "between 10 and 100. " << std::endl;
}
Preface
Before we attack the problem first let's refactor so that we can break it down to a single function so that as we work we don't disturb everything else as well as gain flexibility for testing and simplify readability.
Refactor
/* this code is responsible for doing what is needed to
* only insert unique items */
bool insert( const int& input, int* array, int num_elements ) {
// the fun part!
// more to follow shortly
};
/* gets user input forcing input to be between min and max */
int getUserInput(int min, int max) {
bool found = false;
int result = 0;
/* this can be done with less code but this makes it easy
* to see whats going on */
while ( !found ) {
cout << "Please enter a value between " << min << " and " << max << "." << endl;
cin >> result;
if ( result >= min && result <= max ) {
found = true; //yes we could break or return from here
} else {
cout << result << " invalid. "<< endl;
}
}
return result;
};
void printArray( const int* array, const int& size ) {
for (int i = 0; i < size; i++)
{
cout << array[i] << endl;
}
};
int main()
{
const int totalElements = 20;
int theArray [totalElements] = {0};
int userInput = 0;
int populateCount = 0;
int minVal = 10;
int maxVal = 100;
cout << "Enter " << totalElements << " integers between "
<< minVal << " and " << maxVal << " inclusive. " << endl;
while ( populateCount < numElements )
{
//this will percievably loop until it's good
userInput = getUserInput(minVal, maxVal);
if ( insert( userInput, theArray, populateCount ) )
++populateCount; //increments if we did insert it
}
}
cout << endl;
printArray( theArray, totalElements );
}
Attacking the problem
Ok so now our problem is simple, we just have to write the insert function. There are a couple of choices here, you can check each element in turn which as you said can be slow, O(n), or we could sort the array to make it quick, O(log n) + cost of sorting. Other possibilities I presume aren't available are using a std::set instead of an array, or using STL to do the work of sorting and finding. Note that in these modes insert won't actually do an insertion if the number is already present.
Another unique idea is to use an array of bools size max-min, and simply flag the index of input-min as true when you find it. This will be fast at the cost of size depending upon the gap between min and max. (this is essentially a hash function)
The advantage we are at from a refactor is that you can in turn write and try each of these solutions and even feed them the same canned input now that we've refactored so that you can try and time each one. For timing I would heavily suggest you add lots of numbers and consider greatly expanding the min and max to understand the scalability of each choice