Find multiple modes in an array

I tried to write a function to find the mode(s), but it didn't print out the correct mode(s). The code and example are as below. Thank you for your time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void calMode(int array[], int size)
{
    int counter=1,
	max=0,
	mode=array[0],
	modeCounter=0,  	 //Array size.
	modeNumbers[modeCounter];//Create an array to hold the mode(s) 
    for(int pass=0; pass<size-1; pass++)
    {
        if(array[pass]==array[pass+1])
        {
            counter++;
            if(counter>max)
            {
                max=counter;
                mode=array[pass];
                modeNumbers[modeCounter]=array[pass];
        	modeCounter++;
            }
        }
        else
        {
            counter=1; 
        }
    }
    for(int x=0; x<modeCounter; x++)
    {
	cout << modeNumbers[x] << " ";
    }
}

The test case:
The numbers in ascending order are:
0 1 2 3 4 4 5 5 5 7 8 9
The mode is/are 4 5
TJW wrote:
The numbers in ascending order are:
0 1 2 3 4 4 5 5 5 7 8 9
The mode is/are 4 5


I can assure you that the mode of those numbers is just 5.

You (attempt to) create an array with 0 elements on line 7. Use a vector, then it can expand to the number required.
Last edited on
Hi lastchance:
I attempt to create an array with the elements of 1 to many. It depends on the mode of each test case. The code I wrote could print out the multiple modes of arrays, but it failed to print out the single mode. Is there any way that I can print the correct mode(s) out in all situations? Thank you!
The code that you wrote won't (or, at least, shouldn't) compile. So it certainly wouldn't calculate multiple modes correctly.

Use a vector to hold your modes. Then you can push_back() to expand and resize() to contract.

As I said in my previous post, you attempt to create a size-zero array on line 7 (since that is the size of modeCounter at the time) ... so how do you expect to put anything in it. Declaring a standard array with a size known only at runtime would also be illegal in standard c++ anyway, but that's the least of your problems.
You can try a two-pass version; it's probably easier.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <vector>
#include <string>
using namespace std;

//======================================================================

template<typename T> vector<T> mode( const vector<T> &A )  // Assumption: A already sorted
{
   // Pass 1: find longest run
   int longestRun = 1, currentRun = 1;           // Corresponds to just A[0]
   for ( int i = 1; i < A.size(); i++ )
   {
      currentRun = ( A[i] == A[i-1] ? currentRun + 1 : 1 );
      if ( currentRun > longestRun ) longestRun = currentRun;
   }
   if ( longestRun == 1 ) return A;              // Conveniently also deals with A being empty

   // Pass 2: add anything with longest run to modes
   vector<T> result;
   currentRun = 1;
   for ( int i = 1; i < A.size(); i++ )
   {
      currentRun = ( A[i] == A[i-1] ? currentRun + 1 : 1 );
      if ( currentRun == longestRun ) result.push_back( A[i] );
   }
   return result;
}

//======================================================================

int main()
{
   vector< vector<int> > test = { {},
                                  { 1 },
                                  { 1, 2, 3, 4, 5 },
                                  { 1, 2, 2, 4, 4, 6, 8 },
                                  { 1, 2, 3, 4, 4, 5, 5, 5, 7, 8, 9 } };

// vector< vector<double> > test = { { 3.4, 4.5, 4.5, 6.0, 9.0 , 9.0, 11.0 },
//                                   { 1.0, 5.5, 5.5, 5.5, 7.3 } };

// vector< vector<string> > test = { { "bus", "car", "car", "car", "rocket", "train", "train", "train" } };

   for ( const auto &A : test )
   {
      cout << "Array: ";   for ( auto e : A         ) cout << e << ' ';
      cout << '\n';
      cout << "Modes: ";   for ( auto e : mode( A ) ) cout << e << ' ';
      cout << "\n\n";
   }
}


Array: 
Modes: 

Array: 1 
Modes: 1 

Array: 1 2 3 4 5 
Modes: 1 2 3 4 5 

Array: 1 2 2 4 4 6 8 
Modes: 2 4 

Array: 1 2 3 4 4 5 5 5 7 8 9 
Modes: 5 
My instructor didn't like us to use vector, so I had to try other ways.
Here is the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void calMode(int array[], int size)
{
    int counter=1,
	 max=0,
	 mode=array[0],
	 modeCounter=0,				//Array size.
	 modeNumbers[modeCounter];	//Create an array to hold the mode(s) 
    for(int pass=0; pass<size-1; pass++)
    {
        if(array[pass]==array[pass+1])
        {
            counter++;
            if(counter>max)
            {
                max=counter;
                mode=array[pass];
            }
            if(counter==max || modeNumbers[modeCounter]!=modeNumbers[modeCounter+1]) 
            {
        	modeNumbers[modeCounter]=array[pass];
        	modeCounter++;
	    }
        }
        else
        {
            counter=1; 
        }
    }
	if(modeCounter==0)
	{
	    for(int x=0; x<size; x++)
	    {
		cout << array[x] << " "; //If there is no mode, print out the whole array. (The modes are every number of the array.)
	    }
	}
	else
	{
	    for(int x=0; x<modeCounter; x++)
	    {
	 	cout << modeNumbers[x] << " ";
	    }	
	}
}
1
2
	 modeCounter=0,				//Array size.
	 modeNumbers[modeCounter];	//Create an array to hold the mode(s) 


I give up. Yes, really. I give up.
Topic archived. No new replies allowed.