I've tried to implement an algorithm that would search for both minimum and maximum elements in a given array, and used the ideas from Cormen's Introduction to Algorithms. My code compiles and starts working, outputs the generated random array and then does nothing for a really long time.
Why could that be?
The code is this:
// fast min and max --cormen exercise 1.cpp: entry point
//implemented from a verbal description in cormen's book, p 243
#include "stdafx.h"
#include <vector>
#include <ctime>
#include <cstdlib>
#include <iostream>
struct min_and_max
{
int min, max;
};
min_and_max find_min_and_max(std::vector<int>& A)
{
int n = A.size();
int min, max;
if (n%2 == 1)
min = max = A[0];
if (n%2 == 0)
if (A[0] < A[1])
{
min = A[0];
max = A[1];
}
else
{
min = A[1];
max = A[0];
}
for(int i = 2; i < A.size(); (i + 2))
{
if (A[i] < A[i+1])
{
if (min > A[i])
min = A[i];
if (max < A[i+1])
max = A[i+1];
}
else
{
if (min > A[i+1])
min = A[i+1];
if (max < A[i])
max = A[i];
}
}
min_and_max result;
result.min = min;
result.max = max;
return result;
}
int main()
{
std::srand(std::time(0));
std::vector<int> A(10);
for (auto i = 0; i < A.size(); i++)
{
A[i] = rand() % 1000;
std::cout << A[i] << " ";
}
std::cout << std::endl; //IT GOES AS FAR AS THIS
std::cout << "The array has been analyzed; its' minimum is " << find_min_and_max(A).min << "and its' maximum is " << find_min_and_max(A).max << std::endl;
return 0;
}
for(int i = 2; i < A.size(); (i + 2))
i + 2 won't change the value of i, you need to use i += 2.
The problem lies here:
for(int i = 2; i < A.size(); (i + 2))
You never actually increment i, thus causing an infinite loop.
change it to:
for(int i = 2; i < A.size(); i+=2)
Additional to the given answers, if you're using c++11 you can simplify your algorithm using lambdas and the std::for_each function:
#include <algorithm>
#include <iostream>
#include <cmath>
int main() {
int array[] = { -8, 8, 0, 9, 5, -3, 4, 6, -1, 15, 31 };
int min, max;
// User std::for_each(v.begin(), v.end(), ...) for either vector or list
std::for_each(std::begin(array), std::end(array), [&min, &max](int elem) {
max = std::max(max, elem);
min = std::min(min, elem);
});
std::cout << min << ", " << max << std::endl;
return 0;
}
And maybe it could be even simpler
Update: As #Blastfurnace pointed out, the std::minmax_element function could be used to further reduce the code needed for searching both the min and max element, yielding this shorter version:
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values = { -8, 8, 0, 9, 5, -3, 4, 6, -1, 15, 31 };
auto minAndMax = std::minmax_element(values.begin(), values.end());
std::cout << *minAndMax.first << ", " << *minAndMax.second << std::endl;
return 0;
}
Is important to note that everything done in this answer, besides being OT, is for the sake of learning, to give the OP alternatives to improve his (or her) work and help other users that could have the same requirement.
In any case the algorithm is incorrect because the vector can have the size equal to 0. In this case 1) you try to access alements that are not exist and 2) you return undefined values from the function. The more correct approach is to return indexes of the minimum and maximum elements and in the case if the vector is empty return a pair of A.size().
Related
struct Pair
{
int min;
int max;
};
struct Pair getMinMax(int arr[], int n)
{
struct Pair minmax;
int i;
// If array has even number of elements
// then initialize the first two elements
// as minimum and maximum
if (n % 2 == 0)
{
if (arr[0] > arr[1])
{
minmax.max = arr[0];
minmax.min = arr[1];
}
else
{
minmax.min = arr[0];
minmax.max = arr[1];
}
// Set the starting index for loop
i = 2;
}
// If array has odd number of elements
// then initialize the first element as
// minimum and maximum
else
{
minmax.min = arr[0];
minmax.max = arr[0];
// Set the starting index for loop
i = 1;
}
// In the while loop, pick elements in
// pair and compare the pair with max
// and min so far
while (i < n - 1)
{
if (arr[i] > arr[i + 1])
{
if(arr[i] > minmax.max)
minmax.max = arr[i];
if(arr[i + 1] < minmax.min)
minmax.min = arr[i + 1];
}
else
{
if (arr[i + 1] > minmax.max)
minmax.max = arr[i + 1];
if (arr[i] < minmax.min)
minmax.min = arr[i];
}
// Increment the index by 2 as
// two elements are processed in loop
i += 2;
}
return minmax;
}
// Driver code
int main()
{
int arr[] = { 1000, 11, 445,
1, 330, 3000 };
int arr_size = 6;
Pair minmax = getMinMax(arr, arr_size);
cout << "nMinimum element is "
<< minmax.min << endl;
cout << "nMaximum element is "
<< minmax.max;
return 0;
}
In this qsn we have to return max and min value simultaneously so here struct is made.
I copied this code from GEEKSFORGEEKS site. I was trying this code's approach but stuck in doubt that how here comparisons is being calculates.
In this code i want to know that how comparisons is 3*(n-1)/2 when n=odd?
The above code is the definition of premature optimization. Where you literally are taking the below code that takes 4 int compares per two elements, down to 3, and the cost of making the code hard to read, and easier to write bugs into.
Even in the code written below these could be changed to if() else if(), since they are populated with the same value to start with, both conditions are impossible to be true. But it's not worth making that change to make the reader have to think through if that is actually true.
Trying to be too smart, and you'll only outsmart yourself.
struct Pair
{
int min;
int max;
};
Pair getMinMax(int arr[], int length){
Pair output = {0, 0};
if(length < 1){
return output;
}
output.min = arr[0];
output.max = arr[0];
for(int i= 1; i < length; i++){
if(arr[i] < output.min){
output.min = arr[i];
}
if(arr[i] > output.max){
output.max = arr[i];
}
}
return output;
}
int main()
{
int array[] = { 8, 6, 4, 2, 9, 4};
auto data = getMinMax(array, 6);
std::cout << data.min << " " << data.max;
}
Solution using STL code (C++20) :
#include <algorithm>
#include <vector>
#include <iostream>
struct MinMaxResult
{
int min;
int max;
};
MinMaxResult getMinMax(const std::vector<int>& values)
{
return (values.size() == 0) ?
MinMaxResult{} :
MinMaxResult(std::ranges::min(values), std::ranges::max(values));
}
int main()
{
std::vector<int> values{ 8, 6, 4, 2, 9, 4 };
auto data = getMinMax(values);
std::cout << data.min << ", " << data.max;
return 0;
}
There are answers (good ones imho), but so far none does actually count the number of comparisons. With std::minmax_element you can count the number of comparisons like this:
#include <utility>
#include <vector>
#include <iostream>
#include <algorithm>
template <typename TAG>
struct compare {
static size_t count;
template <typename T>
bool operator()(const T& a,const T& b){
++count;
return a < b;
}
};
template <typename TAG> size_t compare<TAG>::count = 0;
template <typename TAG>
compare<TAG> make_tagged_compare(TAG) { return {};}
int main()
{
std::vector<int> x{1,2,3};
auto c = make_tagged_compare([](){});
auto mm = std::minmax_element(x.begin(),x.end(),c);
std::cout << *mm.first << " " << *mm.second << " " << c.count;
}
Standard algorithms may copy predicates passed to them, hence count is static. Because I want to reuse compare later to count a different algorithm, I tagged it (each lambda expression is of different type, hence it can be used as unique tag). The output is:
1 3 3
It correctly finds min and max, 1 and 3, and needs 3 comparisons to achieve that.
Now if you want to compare this to a different algorithm, it will look very similar to the above. You pass a functor that compares elements and counts the number of comparisons of the algorithm. As example I use a skeleton implementation that does only a single comparison and either returns {x[0],x[1]} or {x[1],x[0]}:
template <typename IT, typename Compare>
auto dummy_minmax(IT first, IT last,Compare c) {
auto second = first+1;
if (c(*first,*second)) return std::pair(*first,*second);
else return std::pair(*second,*first);
}
int main()
{
std::vector<int> x{1,2,3};
auto c = make_tagged_compare([](){});
auto mm = std::minmax_element(x.begin(),x.end(),c);
std::cout << *mm.first << " " << *mm.second << " " << c.count << "\n";
double x2[] = {1.0,2.0,5.0};
auto c2 = make_tagged_compare([](){});
auto mm2 = dummy_minmax(std::begin(x2),std::end(x2),c2);
std::cout << mm2.first << " " << mm2.second << " " << c2.count;
}
Complete example
Implement a function which takes an array of numbers from 1 to 10 and returns the numbers from 1 to 10 which are missing. examples input: [5,2,6] output: [1,3,4,7,8,9,10]
C++ program for the above approach:
#include <bits/stdc++.h>
using namespace std;
// Function to find the missing elements
void printMissingElements(int arr[], int N)
{
// Initialize diff
int diff = arr[0] - 0;
for (int i = 0; i < N; i++) {
// Check if diff and arr[i]-i
// both are equal or not
if (arr[i] - i != diff) {
// Loop for consecutive
// missing elements
while (diff < arr[i] - i) {
cout << i + diff << " ";
diff++;
}
}
}
}
Driver Code
int main()
{
// Given array arr[]
int arr[] = { 5,2,6 };
int N = sizeof(arr) / sizeof(int);
// Function Call
printMissingElements(arr, N);
return 0;
}
How to solve this question for the given input?
First of all "plzz" is not an English world. Second, the question is already there, no need to keep writing in comments "if anyone knows try to help me".
Then learn standard headers: Why should I not #include <bits/stdc++.h>?
Then learn Why is "using namespace std;" considered bad practice?
Then read the text of the problem: "Implement a function which takes an array of numbers from 1 to 10 and returns the numbers from 1 to 10 which are missing. examples input: [5,2,6] output: [1,3,4,7,8,9,10]"
You need to "return the numbers from 1 to 10 which are missing."
I suggest that you really use C++ and get std::vector into your toolbox. Then you can leverage algorithms and std::find is ready for you.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
std::vector<int> missingElements(const std::vector<int> v)
{
std::vector<int> missing;
for (int i = 1; i <= 10; ++i) {
if (find(v.begin(), v.end(), i) == v.end()) {
missing.push_back(i);
}
}
return missing;
}
int main()
{
std::vector<int> arr = { 5, 2, 6 };
std::vector<int> m = missingElements(arr);
copy(m.begin(), m.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
return 0;
}
If you want to do something with lower computational complexity you can have an already filled vector and then mark for removal the elements found. Then it's a good chance to learn the erase–remove idiom:
std::vector<int> missingElements(const std::vector<int> v)
{
std::vector<int> m = { -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (const auto& x: v) {
m[x] = -1;
}
m.erase(remove(m.begin(), m.end(), -1), m.end());
return m;
}
By this approach we are using space to reduce execution time. Here the time complexity is O(N) where N is the no of elements given in the array and space complexity is O(1) i.e 10' .
#include<iostream>
void printMissingElements(int arr[], int n){
// Using 1D dp to solve this
int dp[11] = {0};
for(int i = 0; i < n; i++){
dp[arr[i]] = 1;
}
// Traverse through dp list and check for
// non set indexes
for(int i = 1; i <= 10; i++){
if (dp[i] != 1) std::cout << i << " ";
}
}
int main() {
int arr[] = {5,2,6};
int n = sizeof(arr) / sizeof(int);
printMissingElements(arr, n);
}
void printMissingElements(int arr[], int n,int low, int high)
{
bool range[high - low + 1] = { false };
for (int i = 0; i < n; i++) {
if (low <= arr[i] && arr[i] <= high)
range[arr[i] - low] = true;
}
for (int x = 0; x <= high - low; x++) {
if (range[x] == false)
std:: cout << low + x << " ";
}
}
int main()
{
int arr[] = { 5,2,6,6,6,6,8,10 };
int n = sizeof(arr) / sizeof(arr[0]);
int low = 1, high = 10;
printMissingElements(arr, n, low, high);
return 0;
}
I think this will work:
vector<int> missingnumbers(vector<int> A, int N)
{ vector<int> v;
for(int i=1;i<=10;i++)
v.push_back(i);
sort(A.begin(),A.end());
int j=0;
while(j<v.size()) {
if(binary_search(A.begin(),A.end(),v[j]))
v.erase(v.begin()+j);
else
j++;
}
return v;
}
I'm trying to write a code where there is a research of even numbers and then it deletes the even numbers and then shifts all the other elements.
i is for offset and are the actual position of the elements in the array.
k is the position of the even number in the array.
int k;
for(i=0; i < N; i++)
{
if(Array[i] % 2 == 0)
{
for(k=i+1; k < N; k++)
{
Array[k-1] = Array[k];
}
N--;
}
}
Array=[2,10,3,5,8,7,3,3,7,10] the even numbers should be removed, but a 10
stays in the Array=[10,3,5,7,3,3,7].
Now is more than 3 hours that I'm trying to figure out what's wrong in my code.
This appears to be some sort of homework or school assignment. So what's the actual problem with the posted code?
It is that when you remove an even number at index i, you put the number that used to be at index i + 1 down into index i. Then you continue the outer loop iteration, which will check index i + 1, which is the number that was at the original i + 2 position in the array. So the number that started out at Array[i + 1], and is now in Array[i], is never checked.
A simple way to fix this is to decrement i when you decrement N.
Though already answered, I fail to see the reason people are driving this through a double for-loop, repetitively moving data over and over, with each reduction.
I completely concur with all the advice about using containers. Further, the algorithms solution doesn't require a container (you can use it on a native array), but containers still make it easier and cleaner. That said...
I described this algorithm in general-comment above. you don't need nested loops fr this. You need a read pointer and a write pointer. that's it.
#include <iostream>
size_t remove_even(int *arr, size_t n)
{
int *rptr = arr, *wptr = arr;
while (n-- > 0)
{
if (*rptr % 2 != 0)
*wptr++ = *rptr;
++rptr;
}
return (wptr - arr);
}
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
size_t n = remove_even(arr, sizeof arr / sizeof *arr);
for (size_t i=0; i<n; ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
Output
3 5 7 3 3 7
If you think it doesn't make a difference, I invite you to fill an array with a million random integers, then try both solutions (the nested-for-loop approach vs. what you see above).
Using std::remove_if on a native array.
Provided only for clarity, the code above basically does what the standard algorithm std::remove_if does. All we need do is provide iterators (the array offsets and size will work nicely), and know how to interpret the results.
#include <iostream>
#include <algorithm>
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
auto it = std::remove_if(std::begin(arr), std::end(arr),
[](int x){ return x%2 == 0; });
for (size_t i=0; i<(it - arr); ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
Same results.
The idiomatic solution in C++ would be to use a STL algorithm.
This example use a C-style array.
int Array[100] = {2,10,3,5,8,7,3,3,7,10};
int N = 10;
// our remove_if predicate
auto removeEvenExceptFirst10 = [first10 = true](int const& num) mutable {
if (num == 10 && first10) {
first10 = false;
return false;
}
return num % 2 == 0;
};
auto newN = std::remove_if(
std::begin(Array), std::begin(Array) + N,
removeEvenExceptFirst10
);
N = std::distance(std::begin(Array), newN);
Live demo
You could use a std::vector and the standard function std::erase_if + the vectors erase function to do this:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> Array = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
auto it = std::remove_if(
Array.begin(),
Array.end(),
[](int x) { return (x & 1) == 0 && x != 10; }
);
Array.erase(it, Array.end());
for(int x : Array) {
std::cout << x << "\n";
}
}
Output:
10
3
5
7
3
3
7
10
Edit: Doing it the hard way:
#include <iostream>
int main() {
int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
size_t N = sizeof(Array) / sizeof(int);
for(size_t i = 0; i < N;) {
if((Array[i] & 1) == 0 && Array[i] != 10) {
for(size_t k = i + 1; k < N; ++k) {
Array[k - 1] = Array[k];
}
--N;
} else
++i; // only step i if you didn't shift the other values down
}
for(size_t i = 0; i < N; ++i) {
std::cout << Array[i] << "\n";
}
}
Or simpler:
#include <iostream>
int main() {
int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
size_t N = sizeof(Array) / sizeof(int);
size_t k = 0;
for(size_t i = 0; i < N; ++i) {
if((Array[i] & 1) || Array[i] == 10) {
// step k after having saved this value
Array[k++] = Array[i];
}
}
N = k;
for(size_t i = 0; i < N; ++i) {
std::cout << Array[i] << "\n";
}
}
Here is the program to find the pairs that sums up to 3.
For example:
INPUT : 0,3,5,1,2,4
OUTPUT: 0,3,1,2.
That means it should return all the pairs whose sum is equal to 3.
But I want to reduce the time complexity of this program. Right now I am using two nested for loops.
Can anyone suggest a better method to reduce the time complexity.
#include<iostream>
#include <vector>
using namespace std;
void main()
{
vector<int> v;
vector<int> r;
int x;
cout << "Enter the elements";
for(int i = 0; i < 6; i++)
{
cin >> x;
v.push_back(x);
}
for(int i = 0 ; i < v.size() - 1; i++)
{
for(int j = i + 1; j < v.size(); j++)
{
if(v[i] + v[j] == 3)
{
r.push_back(v[i]);
r.push_back(v[j]);
}
}
}
cout << "\noutput\n";
for(int i = 0 ; i < r.size(); i++)
{
cout<<r[i]<<"\n";
}
}
I'd do two preparation steps; First, eliminate all numbers > 3, as they will not be part of any valid pair. This reduces the complexity of the second step. Second, sort the remaining numbers such that a single walk through can then find all the results.
The walk through approaches the pairs from both ends of the sorted array; if a pair is found, both bounds can be narrowed down; if the current endings do sum up to a value > 3, only one boundary is narrowed.
Runtime complexity is O(N logN), where N is the count of elements <= 3; O(N logN) basically comes from sorting; the two single walk throughs will not count for large Ns.
int main(int argc, char* argv[]) {
const int N = 3;
std::vector<int> input{ 0,3,5,1,2,4};
std::vector<int>v(input.size());
int t=0;
for (auto i : input) {
if (i <= N) {
v[t++]=i;
}
}
std::sort (v.begin(), v.end());
long minIdx = 0;
long maxIdx = v.size()-1;
while (minIdx < maxIdx) {
int minv = v[minIdx];
int maxv = v[maxIdx];
if (minv+maxv == 3) {
cout << minv << '+' << maxv << endl;
minIdx++;maxIdx--;
}
else
minIdx++;
}
return 0;
}
You are searching for all the combinations between two numbers in n elements, more specifically, those that sum up to specific value. Which is a variation of the subset sum problem.
To make this happen you could generate all combinations without repetitions of the indexes of the vector holding the values. Here is an example of how to do this recursively and here is an example of how to do it iteratively, just to get an idea and possibly use it as a benchmark in your case.
Another approaches are dynamic programming and backtracking.
Late answer but works for negative integers too... For first, find the smallest number in the std::vector<int>, then like this answer says, remove all elements (or copy the opposite), which are higher than 3 + minimum. After sorting this std::vector<int> iterate through it from both ends with condition shown bellow:
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
std::vector<int> findPairs(const std::vector<int>& input, const int sum) {
int minElem = INT_MAX;
for(auto lhs = input.begin(), rhs = input.end() - 1; lhs < rhs;
++lhs, --rhs) {
const int elem = (*lhs < *rhs ? *lhs : *rhs);
if(elem < minElem)
minElem = elem;
}
std::vector<int> temp(input.size());
const auto tempBegin = temp.begin();
const auto tempEnd = std::remove_copy_if(input.begin(), input.end(),
temp.begin(), [minElem, sum](int elem) {
return (elem + minElem) > sum;
});
std::sort(tempBegin, tempEnd);
std::vector<int> result;
auto leftIter = tempBegin;
auto rightIter = tempEnd - 1;
while(leftIter < rightIter) {
if(*leftIter + *rightIter == sum) {
result.push_back(*leftIter++);
result.push_back(*rightIter--);
}
else {
if(sum - *leftIter < *rightIter) rightIter--;
else leftIter++;
}
}
return result;
}
int main() {
auto pairs = findPairs({ 0, 3, 5, 1, 2, 4, 7, 0, 3, 2, -2, -4, -3 }, 3);
std::cout << "Pairs: { ";
for(auto it = pairs.begin(); it != pairs.end(); ++it)
std::cout << (it == pairs.begin() ? "" : ", ") << *it;
std::cout << " }" << std::endl;
}
The code above will results the following:
Pairs: { -4, 7, -2, 5, 0, 3, 0, 3, 1, 2 }
I think you can solve this in O(n) with a map.
public void printPairs(int[] a, int v)
{
map<int, int> counts = new map<int, int>();
for(int i = 0; i < a.length; i++)
{
if(map.count(a[i]) == 0)
{
map[a[i]] = 1;
}
else
{
map[a[i]] = map[a[i]] + 1;
}
}
map<int, int>::iterator it = map.begin();
while(it != map.end())
{
int v1 = it->second;
if (map.count(v - v1) > 0)
{
// Found pair v, v1
//will be found twice (once for v and once for v1)
}
}
}
I'm trying to devise an algorithm in the form of a function that accepts two parameters, an array and the size of the array. I want it to return the mode of the array and if there are multiple modes, return their average. My strategy was to take the array and first sort it. Then count all the occurrences of a number. while that number is occurring, add one to counter and store that count in an array m. So m is holding all the counts and another array q is holding the last value we were comparing.
For example: is my list is {1, 1, 1, 1, 2, 2, 2}
then i would have m[0] = 4 q[0] = 1
and then m[1] = 3 and q[1] = 2.
so the mode is q[0] = 1;
unfortunately i have had no success thus far. hoping someone could help.
float mode(int x[],int n)
{
//Copy array and sort it
int y[n], temp, k = 0, counter = 0, m[n], q[n];
for(int i = 0; i < n; i++)
y[i] = x[i];
for(int pass = 0; pass < n - 1; pass++)
for(int pos = 0; pos < n; pos++)
if(y[pass] > y[pos]) {
temp = y[pass];
y[pass] = y[pos];
y[pos] = temp;
}
for(int i = 0; i < n;){
for(int j = 0; j < n; j++){
while(y[i] == y[j]) {
counter++;
i++;
}
}
m[k] = counter;
q[k] = y[i];
i--; //i should be 1 less since it is referring to an array subscript
k++;
counter = 0;
}
}
Even though you have some good answers already, I decided to post another. I'm not sure it really adds a lot that's new, but I'm not at all sure it doesn't either. If nothing else, I'm pretty sure it uses more standard headers than any of the other answers. :-)
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <map>
#include <iostream>
#include <utility>
#include <functional>
#include <numeric>
int main() {
std::vector<int> inputs{ 1, 1, 1, 1, 2, 2, 2 };
std::unordered_map<int, size_t> counts;
for (int i : inputs)
++counts[i];
std::multimap<size_t, int, std::greater<size_t> > inv;
for (auto p : counts)
inv.insert(std::make_pair(p.second, p.first));
auto e = inv.upper_bound(inv.begin()->first);
double sum = std::accumulate(inv.begin(),
e,
0.0,
[](double a, std::pair<size_t, int> const &b) {return a + b.second; });
std::cout << sum / std::distance(inv.begin(), e);
}
Compared to #Dietmar's answer, this should be faster if you have a lot of repetition in the numbers, but his will probably be faster if the numbers are mostly unique.
Based on the comment, it seems you need to find the values which occur most often and if there are multiple values occurring the same amount of times, you need to produce the average of these. It seems, this can easily be done by std::sort() following by a traversal finding where values change and keeping a few running counts:
template <int Size>
double mode(int const (&x)[Size]) {
std::vector<int> tmp(x, x + Size);
std::sort(tmp.begin(), tmp.end());
int size(0); // size of the largest set so far
int count(0); // number of largest sets
double sum(0); // sum of largest sets
for (auto it(tmp.begin()); it != tmp.end(); ) {
auto end(std::upper_bound(it, tmp.end(), *it));
if (size == std::distance(it, end)) {
sum += *it;
++count;
}
else if (size < std::distance(it, end)) {
size = std::distance(it, end);
sum = *it;
count = 1;
}
it = end;
}
return sum / count;
}
If you simply wish to count the number of occurences then I suggest you use a std::map or std::unordered_map.
If you're mapping a counter to each distinct value then it's an easy task to count occurences using std::map as each key can only be inserted once. To list the distinct numbers in your list simply iterate over the map.
Here's an example of how you could do it:
#include <cstddef>
#include <map>
#include <algorithm>
#include <iostream>
std::map<int, int> getOccurences(const int arr[], const std::size_t len) {
std::map<int, int> m;
for (std::size_t i = 0; i != len; ++i) {
m[arr[i]]++;
}
return m;
}
int main() {
int list[7]{1, 1, 1, 1, 2, 2, 2};
auto occurences = getOccurences(list, 7);
for (auto e : occurences) {
std::cout << "Number " << e.first << " occurs ";
std::cout << e.second << " times" << std::endl;
}
auto average = std::accumulate(std::begin(list), std::end(list), 0.0) / 7;
std::cout << "Average is " << average << std::endl;
}
Output:
Number 1 occurs 4 times
Number 2 occurs 3 times
Average is 1.42857
Here's a working version of your code. m stores the values in the array and q stores their counts. At the end it runs through all the values to get the maximal count, the sum of the modes, and the number of distinct modes.
float mode(int x[],int n)
{
//Copy array and sort it
int y[n], temp, j = 0, k = 0, m[n], q[n];
for(int i = 0; i < n; i++)
y[i] = x[i];
for(int pass = 0; pass < n - 1; pass++)
for(int pos = 0; pos < n; pos++)
if(y[pass] > y[pos]) {
temp = y[pass];
y[pass] = y[pos];
y[pos] = temp;
}
for(int i = 0; i < n;){
j = i;
while (y[j] == y[i]) {
j++;
}
m[k] = y[i];
q[k] = j - i;
k++;
i = j;
}
int max = 0;
int modes_count = 0;
int modes_sum = 0;
for (int i=0; i < k; i++) {
if (q[i] > max) {
max = q[i];
modes_count = 1;
modes_sum = m[i];
} else if (q[i] == max) {
modes_count += 1;
modes_sum += m[i];
}
}
return modes_sum / modes_count;
}