I need a function int countDifferentNumbers(int v[], int n) which counts how many different values the array v with n entries contains.
Example:
It should return the result 3 for the array v = {1, 5, 5, 8, 1, 1} because the array contains only 3 different values.
This is how the code looks like so far:
int countDifferentNumbers(int v[], int n)
{
int counter = 0;
for(int i = 0; i < n; ++i)
{
for(int j = i; j < n; ++j)
{
if(v[i] == v[j + 1])
{
cout << "match" << endl;
counter++;
cout << v[i] << endl;
}
}
}
return counter;
}
I would appreciate an explanation of what is wrong in my function and how I need to redesign it.
Note: Unfortunately, I have not found a suitable thread for this either. All threads with my problems were solved in Java and Python languages.
Recently I see more and more answers here on SO that lead users in the wrong direction by giving bad answers.
Also, for C++, the question has already been answered in the comment by Igor Tandetnik, and that should finally be used.
But let me answer the question of the OP as asked. What is wrong with my function? OK, there are several aspects. Let us first look at the style.
You have 0 lines of comments, so the code quality is 0. If you would write comments, then you would already find most bugs by yourself, because then, you need to explain your own wrong statements.
Then please see your source code with my amendments. I added the problems as comment.
// This is just a dumped function and not a minimum reproducible example
// All header files are messing
// Obviously "using namespace std;" was used that should NEVER be done
// The function should retrun an unsigned value, best size_t, because a count can never be negative
// Same for n, that is the size of an array. Can also never be negative
// C-sytle arrays should NEVER be used in C++. NEVER. Use std::vector or std::array instead
int countDifferentNumbers(int v[], int n)
{
int counter = 0; // Now in C++ we can use braced initialzation instead of assignement
for (int i = 0; i < n; ++i)
{
for (int j = i; j < n; ++j)
{
if (v[i] == v[j + 1]) // Accessing out of bounds element
{
cout << "match" << endl; // Now endl needed here. Can all be done in one cout statement in one line
counter++; // Always counting up the same counter for all kind of double numbers.
cout << v[i] << endl;
}
}
}
return counter;
That was one point of the answer. But now the second point. Evene more important. The algorithm or the design is wrong. And finding the correct solution, this thinking before codingt, you need to do, before you write any line of code.
You obviously want to find the count of unique numbers in an array.
Then you could look what is already there on Stackoverflow. You would probaly find 20 answers already that coud give you a hint.
You could use std::unique. Please see here for a description. This function sounds like it does what you want, right? Some example implementation:
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
// If you want to keep the original data, remove the reference-specifier &
size_t countDifferentNumbers(std::vector<int>& v) {
std::sort(v.begin(), v.end()); // Sorting is precondition for std::unique
v.erase(std::unique(v.begin(), v.end()), v.end()); // Erase all non-unique elements
return v.size(); // Return the result
}
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << countDifferentNumbers(test) << '\n'; // SHow result to user
return 0;
}
Then, we could count the occurence of each number in a std::map or std::unordered_map. And the number of counters will be the result. Example:
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
// If you want to keep the original data, remove the reference-specifier &
size_t countDifferentNumbers(std::vector<int>& v) {
std::unordered_map<int, size_t> counter{}; // Here we will count all occurences of different numbers
for (const int i : v) counter[i]++; // Iterate over vector and count different numbers
return counter.size(); // Count of different numbers
}
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << countDifferentNumbers(test) << '\n'; // Show result to user
return 0;
}
But, then, thinking further, about what conatiners we could use, we will find out the answer from Igor Tandetnik. There are 2 containers that can hold unique values only. No double values. And these are: std::set and std::unordered_set., So, we can simply copy the data into one of those containers, and, only unique values will be stored there.
There are many ways to get the data into a set. But the simplest one is to use its range constructor. Then, we have unique elements, and, the containers size function will give the result:
See here: Constructor Number 2.
The result will be a function with one line like this
#include <iostream>
#include <unordered_set>
#include <vector>
// If you want to keep the original data, remove the reference-specifier &
size_t countDifferentNumbers(std::vector<int>& v) {
return std::unordered_set<int>(v.begin(), v.end()).size();
}
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << countDifferentNumbers(test) << '\n'; // Show result to user
return 0;
}
And since functions with one line are often not so usefull, we can also write the final solution:
#include <iostream>
#include <unordered_set>
#include <vector>
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << std::unordered_set<int>(test.begin(), test.end()).size() << '\n'; // Show result to user
return 0;
}
So, by analyzing the problem and choosing the right algorithm and container and using C++, we come to the most easy solution.
Please enable C++17 for your compiler.
first sort the array v. if n >0 then initially there must be one number which is unique so just increment the value of counter once. then with loop check if the two consecutive number are same or not. if same do nothing else increment the value of counter.
if you are writing code in c then use qsort. #include <stdlib.h> add this in header and. use qsort() func
here is the code:
#include <bits/stdc++.h>
using namespace std;
int countDifferentNumbers(int v[] , int n)
{
int counter = 0;
sort(v, v+ n); // if you are writing code in c then just write a decent sort algorithm.
if (n>0 ){
printf("%d\n", v[0]);
counter ++;
}
for(int i = 0; i < n-1; ++i)
{
if(v[i] == v[i+1]){
continue;
} else {
printf("%d\n", v[i+1]);
counter++;
}
}
return counter;
}
int main()
{
int v[] = {1, 5, 5, 8, 1, 1};
int result = countDifferentNumbers(v,6);
printf("unique number %d", result );
return 0;
}
Related
I want to have a function that returns the sum of different (non duplicate) values from an array: if I have {3, 3, 1, 5}, I want to have sum of 3 + 1 + 5 = 9.
My attempt was:
int sumdiff(int* t, int size){
int sum=0;
for (int i=0; i<=size;i++){
for(int j=i; j<=size;j++){
if(t[i]!=t[j])
sum=sum+t[i];
}
}
return sum;
}
int main()
{
int t[4]={3, 3, 1, 5};
cout << sumdiff(t, 4);
}
It returns 25 and I think I know why, but I do not know how to improve it. What should I change?
Put all the items in a set, then count them.
Sets are data structures that hold only one element of each value (i.e., each of their elements is unique; if you try to add the same value more than once, only one instance will be count).
You can take a look in this interesting question about the most elegant way of doing that for ints.
First of all, your loop should be for (int i=0; i<size;i++). Your actual code is accessing out of the bounds of the array.
Then, if you don't want to use STL containers and algorithms (but you should), you can modify your code as follows:
int sumdiff(int* t, int size){
int sum=0;
for (int i=0; i<size;i++){
// check if the value was previously added
bool should_sum = true;
for(int j=0; should_sum && j<i;j++){
if(t[i]==t[j])
should_sum = false;
}
if(should_sum)
sum=sum+t[i];
}
return sum;
}
int main()
{
int t[4]={3, 3, 1, 5};
cout << sumdiff(t, 4);
}
You could:
Store your array contents into an std::unordered_set first. By doing so, you'd essentially get rid of the duplicates automatically.
Then call std::accumulate to compute the sum
**wasthishelpful's answer was exactly what i was talking about. I saw his post after i posted mine.
So, you're trying to check the duplicate number using your inner loop.
However, your outer loop will loop 4 times no matter what which gives you wrong result.
Try,
Do only checking in inner loop. (use a flag to record if false)
Do your sum outside of inner loop. (do the sum when flag is true)
Here is another solution using std::accumulate, but it iterates over the original elements in the call to std::accumulate, and builds the set and keeps a running total as each number in the array is encountered:
#include <iostream>
#include <numeric>
#include <set>
int main()
{
int t[4] = { 3, 3, 1, 5 };
std::set<int> mySet;
int mySum = std::accumulate(std::begin(t), std::end(t), 0,
[&](int n, int n2){return n += mySet.insert(n2).second?n2:0;});
std::cout << "The sum is: " << mySum << std::endl;
return 0;
}
The way it works is that std::insert() will return a pair tbat determines if the item was inserted. The second of the pair is a bool that denotes whether the item was inserted in the set. We only add onto the total if the insertion is successful, otherwise we add 0.
Live Example
Insert array elements into a set and use the std::accumulate function:
#include <iostream>
#include <numeric>
#include <set>
int main()
{
int t[4] = { 3, 3, 1, 5 };
std::set<int> mySet(std::begin(t), std::end(t));
int mySum = std::accumulate(mySet.begin(), mySet.end(), 0);
std::cout << "The sum is: " << mySum << std::endl;
return 0;
}
Is there a good and efficient algorithm in C++ for sampling without replacement that could easily be applied to the following function?
It takes two vectors, new and old, and fills the latter in a loop by repeatedly sampling from the former (rng.i0 is a random number generator function that I use to return a random integer between 0 and given value).
void diluationexpansionstep(std::vector<long> &oldpopulation,
std::vector<long> &newpopulation,
long newpopsize)
{
for (int i = 1; i <= newpopsize;i++) {
int index_a = rng.i0(oldpopulation.size());
newpopulation.push_back(oldpopulation[index_a]);
}
}
Update::
Thank you for helpful responses. Because i want to use my own RNG rather than the inbuilt one in C++ i ended constructing the following Fisher Yates based function where rng.i0 is a function that returns a random intiger between 0 and integer parameter.
void FisherYatesShuffle(vector<long> &indices){
for (int k = 0; k < indices.size(); k++) {
int r = k + rng.i0(indices.size()-k);
swap(indices[k], indices[r]);
}
}
void diluationexpansionstep(std::vector<long> &oldpopulation,
std::vector<long> &newpopulation,
long newpopsize){
vector<long> indices(oldpopulation.size());
std::iota(std::begin(indices),std::end(indices),0);
FisherYatesShuffle(indices);
for (int i = 0; i <= newpopsize-1;i++){
newpopulation.push_back(oldpopulation[indices[i]]);
}
}
As far as i can tell this work accurately and reasonably quickly.
A "good and efficient" algorithm for minimizing developer time and maximizing correctness, using std::random_shuffle from <algorithm>:
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;
vector<long> random_sample_without_replacement(const vector<long>& source, int newpopsize)
{
assert(newpopsize >= 0 && newpopsize <= source.size());
auto result { source };
std::random_shuffle(result.begin(), result.end());
result.resize(newpopsize);
return result;
}
int main() {
vector<long> test { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
auto result { random_sample_without_replacement(test, 5) };
for (auto& e : result) cout << e << " ";
cout << endl;
return 0;
}
Working example here.
I have a big vector with 24.000 elements like :
(1,1,1,1,3,3,3,3,3,3,5,5,5,...etc)
and I want to check how many same elements are in a row like:
4-6-3..etc
I use this code :
static int counter=1;
vector<int>numbers;
for(int n=0;n<numbers.size()-1;n++)
{
if(numbers[n]==numbers[n+1])
{
counter++;
}
else if(numbers[n]!=numbers[n+1])
{
cout<<counter<<endl;
counter=1;
}
}
is there any algorithm that does the same faster;
#rhalbersma basically gave you the right answer. As an addendum, in case you want to rewrite your algorithm in a more standard fashion:
#include <algorithm>
#include <vector>
#include <iterator>
#include <functional>
#include <iostream>
int main()
{
std::vector<int> v { 1, 1, 2, 3, 3, 5, 5, 5 }; // or whatever...
auto i = begin(v);
while (i != end(v))
{
auto j = adjacent_find(i, end(v), std::not_equal_to<int>());
if (j == end(v)) { std::cout << distance(i, j); break; }
std::cout << distance(i, j) + 1 << std::endl;
i = next(j);
}
}
Here is a live example.
Also, when the vector is sorted, this will give you better best-case complexity:
#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>
int main()
{
std::vector<int> v { 1, 1, 2, 3, 3, 5, 5, 5 }; // must be sorted...
auto i = begin(v);
while (i != end(v))
{
auto ub = upper_bound(i, end(v), *i);
std::cout << distance(i, ub) << std::endl;
i = ub;
}
}
Here is a live example.
Your algorithm is O(N) in time, and that seems pretty optimal to me since you have to visit every unique element for comparison. You might still shave off a few cycles here and there e.g. by eliminating the condition inside the else() or by turning on some compiler settings, but algorithmically you are in good shape.
If the input were already sorted, you could do a series of binary searches. That would give you O(N lg N) worst-case complexity but the average case might be considerably lower depending on the average length of equal element sequences.
BTW, as #AndyProwl shows in his answer: the Standard Library is really awesome to do even this kind of low-level algorithmic stuff. The adjacent_find and upper_bound algorithms have well-documented complexities and the iterator conventions will guard you for edge cases that are present in your own code. Once you learn this vocabulary, you can easily use them in your own routines (and when Ranges come to C++, hopefully it'll also easier to compose them).
There is some litle optimization that may give you a few ms:
int size = numbers.size()-1;
static int counter=1;
static int *num1 = &numbers[0];
static int *num2 = &numbers[1];
for(int n=0;n<size;n++)
{
if(*num1==*num2) counter++;
else
{
cout << counter << "\n";
counter=1;
}
num1++;
num2++;
}
cout<<counter<<endl; //Caution, this line is missing in your code!!
Basicaly:
Avoid access to the vector by id: numbers[n] mean that the computer must multiply n*sizeof(int) and add this result to numbers. Is faster to use pointer and increment it, that mean just an add.
How do I iterate through a list of numbers, and how many different ways are there to do it?
What I thought would work:
#include <cstdlib>
#include <iostream>
#include <list>
using namespace std;
int main()
{
int numbers[] = {2, 4, 6, 8};
int i = 0;
for(i=0; i< numbers.size();i++)
cout << "the current number is " << numbers[i];
system("pause");
return 0;
}
I get an error on the for loop line:
request for member 'size' in 'numbers', which is of non-class type 'int[4]'
Unlike a lot of modern languages plain C++ arrays don't have a .size() function. You have a number of options to iterate through a list depending on the storage type.
Some common options for storage include:
// used for fixed size storage. Requires #include <array>
std::array<type, size> collection;
// used for dynamic sized storage. Requires #include <vector>
std::vector<type> collection;
// Dynamic storage. In general: slower iteration, faster insert
// Requires #include <list>
std::list<type> collection;
// Old style C arrays
int myarray[size];
Your options for iteration will depend on the type you're using. If you're using a plain old C array you can either store the size somewhere else or calculate the size of the array based on the size of it's types. Calculating the size of an array has a number of drawbacks outlined in this answer by DevSolar
// Store the value as a constant
int oldschool[10];
for(int i = 0; i < 10; ++i) {
oldschool[i]; // Get
oldschool[i] = 5; // Set
}
// Calculate the size of the array
int size = sizeof(oldschool)/sizeof(int);
for(int i = 0; i < size; ++i) {
oldschool[i]; // Get
oldschool[i] = 5; // Set
}
If you're using any type that provides a .begin() and .end() function you can use those to get an iterator which is considered good style in C++ compared to index based iteration:
// Could also be an array, list, or anything with begin()/end()
std::vector<int> newschool;
// Regular iterator, non-C++11
for(std::vector<int>::iterator num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num; // * gets the number out of the iterator
*num = 5; // Sets the number.
}
// Better syntax, use auto! automatically gets the right iterator type (C++11)
for(auto num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num; // As above
*num = 5;
}
// std::for_each also available
std::for_each(newschool.begin(), newschool.end(), function_taking_int);
// std::for_each with lambdas (C++11)
std::for_each(newschool.begin(), newschool.end(), [](int i) {
// Just use i, can't modify though.
});
Vectors are also special because they are designed to be drop-in replacements for arrays. You can iterate over a vector exactly how you would over an array with a .size() function. However this is considered bad practice in C++ and you should prefer to use iterators where possible:
std::vector<int> badpractice;
for(int i = 0; i < badpractice.size(); ++i) {
badpractice[i]; // Get
badpractice[i] = 5; // Set
}
C++11 (the new standard) also brings the new and fancy range based for that should work on any type that provides a .begin() and .end(). However: Compiler support can vary for this feature. You can also use begin(type) and end(type) as an alternative.
std::array<int, 10> fancy;
for(int i : fancy) {
// Just use i, can't modify though.
}
// begin/end requires #include <iterator> also included in most container headers.
for(auto num = std::begin(fancy); num != std::end(fancy); ++num) {
int current = *num; // Get
*num = 131; // Set
}
std::begin also has another interesting property: it works on raw arrays. This means you can use the same iteration semantics between arrays and non-arrays (you should still prefer standard types over raw arrays):
int raw[10];
for(auto num = std::begin(raw); num != std::end(raw); ++num) {
int current = *num; // Get
*num = 131; // Set
}
You also need to be careful if you want to delete items from a collection while in a loop because calling container.erase() makes all existing iterators invalid:
std::vector<int> numbers;
for(auto num = numbers.begin(); num != numbers.end(); /* Intentionally empty */) {
...
if(someDeleteCondition) {
num = numbers.erase(num);
} else {
// No deletition, no problem
++num;
}
}
This list is far from comprehensive but as you can see there's a lot of ways of iterating over a collection. In general prefer iterators unless you have a good reason to do otherwise.
Change you for loop to
for(i=0; i< sizeof(numbers)/sizeof(int);i++){
In simple words,
sizeof(numbers) mean number of elements in your array * size of primitive type int, so you divide by sizeof(int) to get the number of elements
If you fix it so that it's list<int> numbers = {1,2,3,4}:
Iterating through using iterators:
#include <iterator>
for(auto it = std::begin(numbers); it != std::end(numbers); ++it) { ... }
Iterating through using std::for_each:
#include <algorithm>
#include <iterator>
std::for_each(numbers.begin(), numbers.end(), some_func);
Utilizing a for-each loop (C++11):
for(int i : numbers) { ... }
I didn't see it among the answers but this is imo the best way to do it: Range-based for loop
It is safe, and in fact, preferable in generic code, to use deduction to forwarding reference:
for (auto&& var : sequence).
Minimalist and working example :
#include <list>
#include <iostream>
int main()
{
std::list<int> numbers = {2, 4, 6, 8};
for (const int & num : numbers)
std::cout << num << " ";
std::cout << '\n';
return 0;
}
If your list of numbers is fixed be aware that you can simply write:
#include <iostream>
#include <initializer_list>
int main()
{
for (int i : {2, 4, 6, 8})
std::cout << i << std::endl;
return 0;
}
There is no size function on "plain" C-style arrays. You need to use std::vector if you want to use size, or calculate size through sizeof.
In C++11 you can use array initialization syntax to initialize your vectors, like this:
vector<int> numbers = {2, 4, 6, 8};
Everything else stays the same (see demo here).
You can also use the plain old C containers and use the iterator syntax for the loop:
#include <iostream>
int main()
{
int numbers[] = {2, 4, 6, 8};
int *numbers_end = numbers + sizeof(numbers)/sizeof(numbers[0]);
for (int *it = numbers; it != numbers_end; ++it)
std::cout << "the current number is " << *it << std::endl;
return 0;
}
There is no member function "size" because "numbers" isn't a class. You can not get the array's size this way, you must either know it (or compute it) or use some class to store your numbers.
The easiest way to do it, in my opinion, would be to use a span.
#include <cstdlib>
#include <iostream>
#include <gsl/span>
int main() {
int numbers[] = {2, 4, 6, 8};
for(auto& num : gsl::span(numbers)) {
cout << "the current number is " << num;
}
system("pause");
}
Notes:
Spans are part of the GSL library. To use them, download the library from here, and add the download path to the compilation command, e.g. g++ -o foo foo.cpp -I/path/to/gsl
In C++20, span will be part of the standard, so you would just use std::span and #include <span>.
#include <iostream>
using namespace std;
int main(){
int findMax(int *);
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
int mval = findMax(values);
cout << values << endl << mval;
return 0;
}
//Function to find the maximum value in the array
int findMax(int arr[]){
int localmax = 0;
for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
if(arr[i] > localmax){
localmax = arr[i];
}
}
return localmax;
}
The purpose of this program is for the user to input a space-separated series of values ended by a 0. That array is then to be analyzed to find the max. I figured out how to convert what is originally a char[] into an int[] so that I can use the findMax() function on it without error but the sorting loop seems to have a problem of its own and when "cout << values << endl << mval;" is called, it returns only a memory address instead of what should be a non-spaced sequence of ints. Can anybody explain what I am doing wrong? It seems that I may have made some mistake using the pointers but I cannot figure out what.
Printing values won't print the contents of the array as you expect, it will print the memory location of the first element of the array.
Try something like this instead:
#include <iterator>
#include <algorithm>
// ...
copy(&values[0], &values[MAX], ostream_iterator(cout, " "));
Sorry I can't post actual working code, but your original post is a mess with many syntax and syntactic errors.
EDIT: In the interest of being more complete and more approachable & understandable to beginners, I've written a small program that illustrates 4 ways to accomplish this.
Method 1 uses copy with an ostream_iterator as I've done above.
Method 2 below is probably the most basic & easiest to understand.
Method 3 is a C++0x method. I know the question is tagged C++, but I thought it might be educational to add this.
Method 4 is a C++ approach using a vector and for_each. I've implemented a functor that does the dumping.
Share & Enjoy
#include <iostream>
#include <iterator>
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
struct dump_val : public unary_function<int,void>
{
void operator()(int val)
{
cout << val << " ";
}
};
int main(){
int vals[5] = {1,2,3,4,5};
// version 1, using std::copy and ostream_iterator
copy(&vals[0], &vals[5], ostream_iterator<int>(cout, " "));
cout << endl;
// version 2, using a simple hand-written loop
for( size_t i = 0; i < 5; ++i )
cout << vals[i] << " ";
cout << endl;
// version 3, using C++0x lambdas
for_each(&vals[0], &vals[5], [](int val)
{
cout << val << " ";
}
);
cout << endl;
// version 4, with elements in a vector and calling a functor from for_each
vector<int> vals_vec;
vals_vec.push_back(1);
vals_vec.push_back(2);
vals_vec.push_back(3);
vals_vec.push_back(4);
vals_vec.push_back(5);
for_each( vals_vec.begin(), vals_vec.end(), dump_val() );
cout << endl;
}
When you pass around an array of X it's really a pointer to an array of X that you're passing around. So when you pass values to cout it only has the pointer to print out.
You really should look into using some of the standard algorithms to make your life simpler.
For example to print all the elements in an array you can just write
std::copy(values, values+MAX, std::ostream_iterator<int>(std::cout, "\n"));
To find the max element you could just write
int mval = *std::max_element(values, values+MAX);
So your code becomes
#include <iostream>
using namespace std;
int main(){
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
copy(values, values+MAX, ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values, values+MAX);
return 0;
}
Doing this removes the need for your findMax method altogether.
I'd also re-write your code so that you use a vector instead of an array. This makes your code even shorter. And you can use stringstream to convert strings to numbers.
Something like this should work and is a lot less code than the original.
int main(){
vector<int> values;
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
int temp = 0;
stringstream ss(ivals);
//read the next int out of the stream and put it in temp
while(ss >> temp) {
//add temp to the vector of ints
values.push_back(temp);
}
copy(values.begin(), values.end(), ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values.begin(), values.end());
return 0;
}
Array of int is promoted to a pointer to int when passed to a function. There is no operator << taking ordinary array. If you want to use operator << this way, you need to use std::vector instead.
Note: it is possible technically to distinguish array when passed to a function using template, but this is not implemented for standard operator <<.
for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
sizeof(arr) here is the size of the pointer to the array. C++ will not pass the actual array, that would be grossly inefficient. You'd typically only get one pass through the loop. Declare your function like this:
int findMax(int* arr, size_t elements) {
//...
}
But, really, use a vector.
Oh, hang on, the question. Loop through the array and print each individual element.