Get the maximum number from an integer array in C++ - c++

I have another task for my school and it is:
Write a program which will output the largest from three inputed numbers
So far I have done this:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int* numbers = new int[3];
for(int i = 0; i < 3; i++) {
cout << "Input number no. " << (i + 1);
cin >> numbers[i];
cout << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Is there a helper function/method in C++ which will find a largest number in my numbers array?

There's an algorithm that finds the maximal element in a container (std::max_element), but that's inappropriate. Your situation can be solved with constant memory consumption, so you don't need to store all numbers. At any given point, you just need to remember the current maximum.
Imagine you had to process one gazillion numbers. Then storing them all would not be desirable.
Of course, internally the max_element algorithm does the same as I just suggested, but it assumes that you already have the container anyway. If you don't, then just update the maximum on the fly. The boost.accumulators library has something to do that, but I'm sure you can write this yourself — it should only take one or two lines.

In the following code snippet, max will contain the highest number from the list:
int i;
int max=numbers[0];
for(i=1;i<3;i++)
{
if(numbers[i]>max) max=numbers[i];
}
Note: Your array looks too small - it has a size of two and I'm pretty sure you want a size of three.

You don't need an array here. Just look at the numbers as they come in:
int largest = std::numeric_limits<int>::min();
for (int i = 0; i < 3; ++i) {
int value;
std::cin >> value;
if (largest < value)
largest = value;
}

Related

Issues with checking an array moving both forwards and backwards simultaneously and issue printing values stored in a pointer array

Preface: Currently reteaching myself C++ so please excuse some of my ignorance.
The challenge I was given was to write a program to search through a static array with a function and return the indices of the number you were searching for. This only required 1 function and minimal effort so I decided to make it more "complicated" to practice more of the things I have learned thus far. I succeeded for the most part, but I'm having issues with my if statements within my for loop. I want them to check 2 separate spots within the array passed to it, but it is checking the same indices for both of them. I also cannot seem to get the indices as an output. I can get the correct number of memory locations, but not the correct values. My code is somewhat cluttered and I understand there are more efficient ways to do this. I would love to be shown these ways as well, but I would also like to understand where my error is and how to fix it. Also, I know 5 won't always be present within the array since I'm using a pseudo random number generator.
Thank you in advance.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// This is supposed to walk throught the array both backwards and forwards checking for the value entered and
// incrementing the count so you know the size of the array you need to create in the next function.
int test(int A[], int size, int number) {
int count = 0;
for (int i = 0; i <= size; i++, size--)
{
if (A[i] == number)
count++;
// Does not walk backwards through the array. Why?
if (A[size] == number)
count++;
}
cout << "Count is: " << count << endl;
return (count);
}
// This is a linear search that creates a pointer array from the previous "count" variable in function test.
// It should store the indices of the value you are searching for in this newly created array.
int * search(int A[], int size, int number, int arr_size){
int *p = new int[arr_size];
int count =0;
for(int i = 0; i < size; i++){
if(A[i]==number) {
p[count] = i;
}
count++;
}
return p;
}
int main(){
// Initializing the array to zero just to be safe
int arr[99]={0},x;
srand(time(0));
// Populating the array with random numbers in between 1-100
for (int i = 0; i < 100; i++)
arr[i]= (rand()%100 + 1);
// Was using this to check if the variable was actually in the array.
// for(int x : arr)
// cout << x << " ";
// Selecting the number you wish to search for.
// cout << "Enter the number you wish to search for between 1 and 100: ";
// cin >> x;
// Just using 5 as a test case.
x = 5;
// This returns the number of instances it finds the number you're looking for
int count = test(arr, (sizeof(arr)/4), x);
// If your count returns 0 that means the number wasn't found so no need to continue.
if(count == 0){
cout << "Your number was not found " << endl;
return 0;
}
// This should return the address array created in the function "search"
int *index = search(arr, (sizeof(arr)/4), x, count);
// This should increment through the array which address you assigned to index.
for(int i=0; i < count; i++) {
// I can get the correct number of addresses based on count, just not the indices themselves.
cout << &index[i] << " " << endl;
}
return 0;
}
I deeply appreciate your help and patience as well as I want to thank you again for your help.

avg, biggest and sum in unknown sized array c++

Im trying to write a console application in c++ that will let the user input a series of numbers and the program should get the sum of all numbers, the average number, the largest and the second largest number.
For example:
Enter a couple of numbers : 10 12 -5 20 -2 15 0
Sum = 50
Average value = 8.3
Largest number = 20
Second largest = 15
#include<iostream>
#include<conio.h>
using namespace std;
int main( )
{
int a[5];
cout << "We are going to find the max value"<< endl;
int x;
for (x=0; x<5; x++)
{
cout<<"insert values"<<x+1<<endl;
cin>>a[x];
}
int max;
int min;
max = a[0];
min = a[0];
int e=0;
while (e<5)
{
if (a[e]>max)
{
max = a[e];
}
e++;
}
cout<<"Max value in the array is.."<<max<<endl;
getch();
return 0;
}
This is my progress so far.
Although, I have some concerns.
How do I let the user input the numbers like in the example and store them in a array with unknown size?
I'll try to figure out a way to count the avg, sum and second largest while waiting for this answer :)
Thanks!
To input an unknown number of elements, you use std::vector, inputting
until the user tells you to stop, typically by inputting an end of file:
std::vector<int> values;
int i;
while ( std::cin >> i ) {
values.push_back( i ) ;
}
If you're looking for some other type a signal for the end, you'll
probably have to read line by line, checking whether the line contains
your end criteron, and then use std::istringstream to parse the
integer.
For the rest: it may not correspond to the goal of the exercise, but
the standard library has a couple of functions which could make things
significantly simpler: std::max_element, for example, or
std::accumulate. And <conio.h> is not very portable, and is
deprecated on the systems which do support it.
If you can't use std::vector, you might want to learn about dynamic memory allocation.
int *a = new int[size];

Need advice on improving my code: Search Algorithm

I'm pretty new at C++ and would need some advice on this.
Here I have a code that I wrote to measure the number of times an arbitrary integer x occurs in an array and to output the comparisons made.
However I've read that by using multi-way branching("Divide and conqurer!") techniques, I could make the algorithm run faster.
Could anyone point me in the right direction how should I go about doing it?
Here is my working code for the other method I did:
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
vector <int> integers;
int function(int vectorsize, int count);
int x;
double input;
int main()
{
cout<<"Enter 20 integers"<<endl;
cout<<"Type 0.5 to end"<<endl;
while(true)
{
cin>>input;
if (input == 0.5)
break;
integers.push_back(input);
}
cout<<"Enter the integer x"<<endl;
cin>>x;
function((integers.size()-1),0);
system("pause");
}
int function(int vectorsize, int count)
{
if(vectorsize<0) //termination condition
{
cout<<"The number of times"<< x <<"appears is "<<count<<endl;
return 0;
}
if (integers[vectorsize] > x)
{
cout<< integers[vectorsize] << " > " << x <<endl;
}
if (integers[vectorsize] < x)
{
cout<< integers[vectorsize] << " < " << x <<endl;
}
if (integers[vectorsize] == x)
{
cout<< integers[vectorsize] << " = " << x <<endl;
count = count+1;
}
return (function(vectorsize-1,count));
}
Thanks!
If the array is unsorted, just use a single loop to compare each element to x. Unless there's something you're forgetting to tell us, I don't see any need for anything more complicated.
If the array is sorted, there are algorithms (e.g. binary search) that would have better asymptotic complexity. However, for a 20-element array a simple linear search should still be the preferred strategy.
If your array is a sorted one you can use a divide to conquer strategy:
Efficient way to count occurrences of a key in a sorted array
A divide and conquer algorithm is only beneficial if you can either eliminate some work with it, or if you can parallelize the divided work parts accross several computation units. In your case, the first option is possible with an already sorted dataset, other answers may have addressed the problem.
For the second solution, the algorithm name is map reduce, which split the dataset in several subsets, distribute the subsets to as many threads or processes, and gather the results to "compile" them (the term is actually "reduce") in a meaningful result. In your setting, it means that each thread will scan its own slice of the array to count the items, and return its result to the "reduce" thread, which will add them up to return the final result. This solution is only interesting for large datasets though.
There are questions dealing with mapreduce and c++ on SO, but I'll try to give you a sample implementation here:
#include <utility>
#include <thread>
#include <boost/barrier>
constexpr int MAP_COUNT = 4;
int mresults[MAP_COUNT];
boost::barrier endmap(MAP_COUNT + 1);
void mfunction(int start, int end, int rank ){
int count = 0;
for (int i= start; i < end; i++)
if ( integers[i] == x) count++;
mresult[rank] = count;
endmap.wait();
}
int rfunction(){
int count = 0;
for (int i : mresults) {
count += i;
}
return count;
}
int mapreduce(){
vector<thread &> mthreads;
int range = integers.size() / MAP_COUNT;
for (int i = 0; i < MAP_COUNT; i++ )
mthreads.push_back(thread(bind(mfunction, i * range, (i+1) * range, i)));
endmap.wait();
return rfunction();
}
Once the integers vector has been populated, you call the mapreduce function defined above, which should return the expected result. As you can see, the implementation is very specialized:
the map and reduce functions are specific to your problem,
the number of threads used for map is static,
I followed your style and used global variables,
for convenience, I used a boost::barrier for synchronization
However this should give you an idea of the algorithm, and how you could apply it to similar problems.
caveat: code untested.

How do I drop the lowest value?

I'm pretty new to C++, and I need help figuring out the code for dropping the lowest value of a randomly generated set of numbers. Here is my code so far:
//Create array and populate the array with scores between 55 and 10
// Drop lowest Score
#include <iostream>
#include <cstdlib>//for generating a random number
#include <ctime>
#include <iomanip>
#include <algorithm>
#include <vector>
using namespace std;
//function prototype
int *random (int);
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
//random function, generates random numbers between 55 and 100 ??
int *random(int num)
{ int *arr; //array to hold numbers
//return null if zero or negative
if (num <= 0)
return NULL;
//allocate array
arr = new int[num];
//seed random number generator
srand(time (0));
//populate array
for (int count = 0; count < num; count++)
arr[count] = (rand()%(45) +55);
//return pointer
//
return arr;
}
For this piece of code, how would I sort or find the lowest score to drop it after the function returns the random numbers?
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
Your suggestions are appreciated!
In general, to find the lowest value in an array, you can follow this psuedo-algorithm:
min = array[0] // first element in array
for (all_values_in_array)
{
if (current_element < min)
min = current_element
}
However, you can't "drop" a value out of a static array. You could look into using a dynamic container (eg. vector), or swapping the lowest value with the last value, and pretending the size of the array is 1 less. Another low level option would be to create your own dynamic array on the heap, however, this is probably more complicated than you are looking for.
Using an vector would be much easier. To drop the lowest element, you just have to sort in reverse order, then remove the last element. Personally, I would recommend using a vector.
The obvious approach to find the smallest element is to use std::min_element(). You probably want to use std::vector<T> to hold your elements but this isn't absolutely necessary. You can remove the smallest value from an array like this:
if (count) {
int* it = std::min_element(array, array + count);
std::copy(it + 1, array + count--, it);
}
Assuming you, reasonable used std::vector<int> instead, the code would look something like this:
if (!array.empty()) {
array.erase(std::min_element(array.begin(), array.end()));
}
First find the index of the lowest number:
int lowest_index=0, i;
for (i=0; i<20; i++)
if (arr[i]<arr[lowest_index])
lowest_index=i;
Now that we know the index, move the numbers coming after that index to overwrite the index we found. The number of numbers to move will be 19 minus the found index. Ie, if index 2 (the third number, since the first is at index 0) is lowest, then 17 numbers comes after that index, so that's how many we need to move.
memcpy(&arr[lowest_index],&arr[lowest_index+1],sizeof(int)*(19-lowest_index))
Good luck!
Sort the array ascending.
The lowest value will be at the beginning of the array.
Or sort the array descending and remove the last element.
Further to what others have said, you may also choose to use something like, perhaps a std::list. It's got sorting built-in, also offering the ability to define your own compare function for two elements. (Though for ints, this is not necessary)
First, I typically typedef the vector or list with the type of the elements it will contain. Next, for lists I typedef an iterator - though both of these are merely a convenience, neither is necessary.
Once you've got a list that will holds ints, just add them to it. Habit and no need to do otherwise means I'll use .push_back to add each new element. Once done, I'll sort the list, grab the element with the lowest value (also the lowest 'index' - the first item), then finally, I'll remove that item.
Some code to muse over:
#include <cstdio>
#include <cstdlib>
#include <list>
using namespace std;
typedef list<int> listInt;
typedef listInt::iterator listIntIter;
bool sortAsc(int first, int second)
{
return first < second;
}
bool sortDesc(int first, int second)
{
return first > second;
}
int main (void)
{
listInt mList;
listIntIter mIter;
int i, curVal, lowestScore;
for (i=1; i<=20; i++)
{
curVal = rand()%45 + 55;
mList.push_back(curVal);
printf("%2d. %d\n", i, curVal);
}
printf("\n");
mList.sort();
// mList.sort(sortAsc); // in this example, this has the same effect as the above line.
// mList.sort(sortDesc);
i = 0;
for (mIter=mList.begin(); mIter!=mList.end(); mIter++)
printf("%2d. %d\n", ++i, *mIter);
printf("\n");
lowestScore = mList.front();
mList.pop_front();
printf("Lowest score: %d\n", lowestScore);
return 0;
}
Oh, and the choice to use printf rather than cout was deliberate too. For a couple of reasons.
Personal preference - I find it easier to type printf("%d\n", someVar);
than cout << someVar << endl;
Size - built with gcc under windows, the release-mode exe of this example is 21kb.
Using cout, it leaps to 459kb - for the same functionality! A 20x size increase for no gain? No thanks!!
Here's an std::list reference: http://www.cplusplus.com/reference/stl/list/
In my opinion the most optimal solution to your problem would be to use a linked list to store the numbers, this way you can use an algorithm with complexity O(N) = N to find the smallest element in the list, it is a similar finding method given by user1599559 or Mikael Lindqvist, you only need stored together with the minimum value the pointer to the Item(ItemX) in the linked list that store it, then to eliminate Item X just tell Item X - 1 points to Item X + 1 and free memory allocated by Item X

Finding Palindromes from the product of two numbers with N digits

My code compiles but seems as if it may never find the answer. This is odd since I have looked at code that is almost identical that finishes in seconds.
Here is my code:
#include <iostream>
#include <sstream>
int main()
{
for(int i = 999; i >=100; i--)
{
for(int j=999; j>=100;j--)
{
int num = (i*j);
std::string number;
std::string temp;
std::string reversed;
std::stringstream out;
out << num;
number = out.str();
temp = number;
std::reverse(temp.begin(),temp.end());
if( temp == number)
{
std::cout << number << std::endl;
}
}
}
std::cin.get();
return 0;
}
Now here is code that I know works and works incredibly fast. I don't see what we are doing differently.
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
// Count down from largest to smallest, so first palindrome found is the largest
unsigned biggestProduct = 0;
for(unsigned n1=999; n1>=100; --n1) {
for(unsigned n2=999; n2>=100; --n2) {
unsigned thisProduct = n1 * n2;
if(thisProduct > biggestProduct) {
stringstream strmProduct;
string strProductReverse;
strmProduct << n1 * n2;
strProductReverse = strmProduct.str();
reverse(strProductReverse.begin(), strProductReverse.end());
if(strmProduct.str() == strProductReverse)
biggestProduct = thisProduct;
}
}
}
cout << biggestProduct << endl;
cin.get();
return 0;
}
for(int i = 999; i <=100; i--)
Will this ever run (same for j)? :)
for(int i = 999; i >=100; i--)
The biggest difference is this line if(thisProduct > biggestProduct). If the product is smaller than the current biggest you don't have to check whether is palindrome.
OK, assuming a correction to the for loops, there's an important difference in the two pieces of code. The second faster piece of code only attempts to find the largest palindrome, so it avoids a lot of work. Your code attempts to find all palindromes which is obviously a harder problem and is going to take more time.
The difference between the two is that the first tests for palindromeness for every i*j, while the other only tests i*j greater than the biggest palindrome its already found.
It can be made slightly faster by going from j= i to j>=100 and earlying out when i*j<= biggestProduct or when i*i<= biggestProduct.
Here are couple issues I can point to:
This line of code: for(int j=999; j>=100;j--) can be reduced to for(int j=999; j>=i-1;j--).This is to avoid running through number twice.
example: for i=999 you will go through j counter, starting with 999, followed by 998, 997, etc. It would save time if you skip everything lower or equal to 998 since i=<998 and j=999 would make those combinations
The second hint is in the question: you are looking for the largest, meaning that the first palindrome is the largest. So you need to filter whatever combination you have beyond that. You have it in the second code by adding if(thisProduct > biggestProduct).
Also steps for the counter can be crucial. From this discussion I found that changing the step size to 2 could be useful.
Last but not least is strings. I learnt here also that making strings could be computationally expensive. Editing the block with std::string could be another option.