I am writing a program that finds the mode of a vector. I need to figure out how to detect if there are multiple modes. Right now it is kind of a flop. How do I detect multiple modes?
#include<iostream>
#include<vector>
usingnamespace std;
int main() {
vector<int>mode;
int num;
int max = 0;
int result;
cout << "Give me numbers and I will find a mode. Enter -1 when you are ready.\n ";
while(num !=-1) {
num = 0;
cin >> num;
if(num!=-1){
mode.push_back(num);
}
}
int freq = 0;
for(int x=0; x<mode.size(); x++){///bubble sort technique
for(int y=0; y<mode.size()-1; y++){
if(mode[y]>mode[y+1]){
int xd = mode[y+1];
mode[y+1] = mode[y];
mode[y] = xd;
}
}
}
int mult[mode.size()] = {};
for (int i = 0;i < mode.size();i++) {
if(mode[i] == mode[i + 1]) {
freq++;
}
else {
freq = 0;// if number[i] is equal to the next number,frequency increases.
}
if (freq > max) {
max = freq;
result = mode[i]; // if the frequency is bigger than the max frequeny,the result should be the number[i]
mult[i] = mode[i];
result = 1;
}
elseif (max == 0) {
result = 0;
}
}
if(result == 0) {
cout << "there is no mode." << endl;
}
elseif(result == 1){
cout << "the mode is: " << max << endl;
}
}
I am not really sure what the "mode of the vector" is. Could you explain?
Imagine you have a following numbers {1, 2, 2, 3, 4, 5, 5, 5, 6}
What should the result be?
#include <iostream>
#include <vector>
#include <algorithm>
usingnamespace std;
//======================================================================
template <class T> vector<T> mode( const vector<T> &v, int &maxCount ) // *** MUST SORT v BEFORE USE ***
{
vector<T> m; // to hold (and ultimately return) the most common values
if ( v.size() == 0 ) // trivial case; empty vector
{
maxCount = 0;
return m;
}
T current = v[0]; // current is the "last known value"; initialise with start of the array
int counter = 1; // counter holds the number of occurrences of current
maxCount = counter; // maxCount holds the maximum number of occurrences of any value
m.push_back( current ); // m holds the modes (i.e. the most frequent values)
for ( int i = 1; i < v.size(); i++ ) // loop through the remaining elements of v
{
if ( v[i] == current ) // if the same as the current value ...
{
counter++;
if ( counter > maxCount ) // if a new modal value ...
{
m.clear(); // empty the old modal vector ...
m.push_back( current ); // ... and put the new mode in
maxCount = counter;
}
elseif ( counter == maxCount ) // if the same as the modal value ...
{
m.push_back( current ); // add to the list of modes
}
}
else // start counting on a new value
{
current = v[i];
counter = 1;
if ( counter == maxCount ) m.push_back( current ); // add to modes only if modal count is 1
}
}
return m;
}
//======================================================================
int main()
{
vector<int> v = { 9, 2, 2, 7, 5, 2, 6, 5, 5, 1 };
int maxNumber;
sort( v.begin(), v.end() );
vector<int> m = mode( v, maxNumber );
cout << "Mode(s): "; for ( auto e : m ) cout << e << " ";
cout << "\nMaximum count: " << maxNumber;
}
@j rod - if you are put off by the templated function and want to restrict yourself to integers only then you can simplify lines 10-20 as
1 2 3 4 5 6 7 8 9 10 11
vector<int> mode( vector<int> v, int &maxCount ) // *** MUST SORT v BEFORE USE ***
{
vector<int> m; // to hold (and ultimately return) the most common values
if ( v.size() == 0 ) // trivial case; empty vector
{
maxCount = 0;
return m;
}
int current = v[0]; // current is the "last known value"; initialise with start of the array
@coder777
It does not output the correct mode.
@Thomas1965
The 'mode' is the value that occurs the most - with your value set {1, 2, 2, 3, 4, 5, 5, 5, 6}, output should be '5'
struct NumberInfo
{
int num;
int count;
};
int main()
{
vector<NumberInfo> numbers;
for (int num; cin >> num;)
{
auto pos = find_if(numbers.begin(), numbers.end(),
[num](NumberInfo& info)
{
return info.num == num;
});
if (pos != numbers.end())
{
(*pos).count++;
}
else
{
numbers.push_back(NumberInfo{num, 1});
}
}
// sort the vector according to the NumberInfo.count
sort(numbers.begin(), numbers.end(), [](const NumberInfo& ni1, const NumberInfo& ni2)
{
return ni1.count > ni2.count;
});
// display the all the numbers and their count - just for test
for (auto ni&: numbers)
cout << ni.num << "\t" << ni.count << "\n";
// TODO display the numbers with the same highest count
for (int i = 0;i < mode.size();i++) {
if(mode[i] == mode[i + 1]) {
freq++;
}
else {
freq = 0;// if number[i] is equal to the next number,frequency increases.
}
if (freq > max) {
max = freq;
result = mode[i]; // if the frequency is bigger than the max frequeny,the result should be the number[i]
mult[i] = mode[i];
result = 1;
}
elseif (max == 0) {result = 0;}
}
if(mode.empty() result == 0) {
cout << "there is no mode." << endl;
}
elseif(result == 1){
cout << "the mode is: " << result max << endl;
}
}
#include<iostream>
#include<vector>
usingnamespace std;
int main() {
vector<int>mode;
int num;
int maxi = 0;
vector<int>result;
cout << "Give me numbers and I will find a mode. Enter -1 when you are ready.\n ";
while(num !=-1) {
num = 0;
cin >> num;
if(num!=-1){
mode.push_back(num);
}
}
int freq = 0;
for(int x=0; x<mode.size(); x++){///bubble sort technique
for(int y=0; y<mode.size()-1; y++){
if(mode[y]>mode[y+1]){
int xd = mode[y+1];
mode[y+1] = mode[y];
mode[y] = xd;
}
}
}
int mult[mode.size()] = {};
for (int i = 0;i < mode.size();i++) {
if(mode[i] == mode[i + 1]) {
freq++;
}
else {
freq = 0;// if number[i] is equal to the next number,frequency increases.
}
for(int i = 0; i < mode.size(); i++){
if (freq > maxi) {
maxi = freq;
result.push_back(mode[i]); // if the frequency is bigger than the max frequeny,the result should be the number[i]
mult[i] = mode[i];
}
}
}
if(result.size() == 1){
cout << "the mode is: " << result[0] << endl;
}
else{
cout << "The modes are: ";
for(int i = 0; i < result.size(); i++){
cout << result[i] << " ";
}
}
}
@j rod
Is there any chance of making some cosmetic changes to your code to make it easier to read:
- what is in mode[] is NOT a mode: could you just call it numbers[] or something?
- you don't need mult[] at all (unless you are also going to do a histogram) - remove it?
- please INDENT CONSISTENTLY (preferably with spaces, not tabs)
Other things:
- when you go on to a new value freq needs to be set to 1, not 0 (line 44)
- you are going to use values beyond the end of your array in line 39
- when you get a single new mode ... you need to empty all previous ones, or they'll just accumulate.
Have a look at my earlier code sample - it should translate reasonably easily to what you are doing.
Have a look at my earlier code sample - it should translate reasonably easily to what you are doing
lastchance - you're being your usual modest self, in fact that program was just great and did everything OP wanted. I've saved it myself for future reference