2

i have a task where i need to find the mode of an array. which means i am looking for the int which is most frequent. i have kinda finished that, but the task also says if there are two modes which is the same, i should return the smallest int e.g {1,1,1,2,2,2} should give 1 (like in my file which i use that array and it gives 2)

public class theMode
{
public theMode()
{
    int[] testingArray = new int[] {1,1,1,2,2,2,4};
    int mode=findMode(testingArray);
    System.out.println(mode);
}

public int findMode(int[] testingArray)
{
    int modeWeAreLookingFor = 0;
    int frequencyOfMode = 0;

    for (int i = 0; i < testingArray.length; i++)
    {
        int currentIndexOfArray = testingArray[i];
        int frequencyOfEachInArray = howMany(testingArray,currentIndexOfArray);

        if (frequencyOfEachInArray > frequencyOfMode)
        {
            modeWeAreLookingFor = currentIndexOfArray;
            frequencyOfMode = modeWeAreLookingFor;

        }
    }
    return modeWeAreLookingFor;
    }

public int howMany(int[] testingArray, int c)
{
    int howManyOfThisInt=0;
    for(int i=0; i < testingArray.length;i++)
    {
        if(testingArray[i]==c){
            howManyOfThisInt++;
        }
    }
    return howManyOfThisInt;
}


public static void main(String[] args)
{
    new theMode();
}
}

as you see my algorithm returns the last found mode or how i should explain it.

6 Answers 6

1

I'd approach it differently. Using a map you could use each unique number as the key and then the count as the value. step through the array and for each number found, check the map to see if there is a key with that value. If one is found increment its value by 1, otherwise create a new entry with the value of 1.

Then you can check the value of each map entry to see which has the highest count. If the current key has a higher count than the previous key, then it is the "current" answer. But you have the possibility of keys with similar counts so you need to store each 'winnning' answer.

One way to approach this is to check each map each entry and remove each entry that is less than the current highest count. What you will be left with is a map of all "highest counts". If you map has only one entry, then it's key is the answer, otherwise you will need to compare the set of keys to determine the lowest.

Sign up to request clarification or add additional context in comments.

3 Comments

i have tried with an hashmap befor but i found it very messy. also since its not as convenient like python with getting keys/values i try to keep it this way with only one array. thank you for input but i want to solve it this way, i hope there is a way though
As the other answer has suggested, you will need some way storing the data "this number has n counts". You could choose to store it an array of arrays (position 0 is the number, position 1 is the count), but this is really what a Map is for. Whichever structure you choose, you still need to store the data so that you can decide whether the current count of the number n is the same count, and if it is, whether your current number is lower than the previous number with the same count. Maybe if you verbalised the algorithm in pseudo-code before coding, it might help you think about your approach.
ok, lets say that i did it. with a HashMap<Integer, Integer> and a loop that puts all new integers in HashMap<Integer, 0> and if the HashMap.containsKey the 2nd index of the hashMAp will be incremented. still when i want to check which has more, its hard to access the keyvalue. then only thing i can access is the values with .get(theInteger). is it impossible to solve "my" way?
1

Hint: You're updating ModeWeAreLookingFor when you find a integer with a strictly higher frequency. What if you find an integer that has the same frequency as ModeWeAreLookingFor ?

Extra exercice: In the first iteration of the main loop execution, you compute the frequency of '1'. On the second iteration (and the third, and the fourth), you re-compute this value. You may save some time if you store the result of the first computation. Could be done with a Map.

Java code convention states that method names and variable name should start with a lower case character. You would have a better syntax coloring and code easier to read if you follow this convention.

2 Comments

fix'd:) yeah i understand it has to do something at that point, since that is the one im outputting. i just find it hard to visual it abstractley when im looping the howMany.
could you help me more, baldrick?
0

this might work with a little modification.

http://www.toves.org/books/java/ch19-array/index.html#fig2

if ((count > maxCount) || (count == maxCount && nums[i] < maxValue)) {
    maxValue = nums[i];
    maxCount = count;
}

1 Comment

yeah, i solved it with some help with my teacher. what helped during the modification was a print in the for-loop with all the variables, so we could follow up. the complete code will be put as a new reply, thanks for your help though since it probably would helped me.
0

since it seems there are no other way, i did a hashmap after all. i am stuck once again in the logics when it comes to comparing frequencys and and the same time picking lowest integer if equal frequencys.

        public void theMode()
    {
        for (Integer number: intAndFrequencyMap.keySet())
        {
            int key = number;
            int value = intAndFrequencyMap.get(number);
            System.out.println("the integer: " +key + " exists " + value + " time(s).");
            int lowestIntegerOfArray = 0;
            int highestFrequencyOfArray = 0;
            int theInteger = 0;
            int theModeWanted = 0;

            if (value > highestFrequencyOfArray)
            {
                highestFrequencyOfArray = value;
                theInteger = number;
            }
            else if (value == highestFrequencyOfArray)
            {
                if (number < theInteger)
                {
                    number = theInteger;
                }
                else if (number > theInteger)
                {

                }
                else if (number == theInteger)
                {
                    number = theInteger;
                }
            }
        }
    }

Comments

0

Completed:

import java.util.Arrays;

public class TheMode                                                                                                  
{
    //Probably not the most effective solution, but works without hashmap
    //or any sorting algorithms

public TheMode()
{
    int[] testingArray = new int[] {2,3,5,4,2,3,3,3};
    int mode = findMode(testingArray);
    System.out.println(Arrays.toString(testingArray));
    System.out.println("The lowest mode is: " + mode);

    int[] test2 = new int[] {3,3,2,2,1};
    int mode2=findMode(test2);
    System.out.println(Arrays.toString(test2));
    System.out.println("The lowest mode is: " +mode2);

    int[] test3 = new int[] {4,4,5,5,1};
    int mode3 = findMode(test3);
    System.out.println(Arrays.toString(test3));
    System.out.println(The lowest mode is: " +mode3);
}

public int findMode(int[] testingArray)
{
    int modeWeAreLookingFor = 0;
    int frequencyOfMode = 0;

    for (int i = 0; i < testingArray.length; i++)
    {
        int currentIndexOfArray = testingArray[i];
        int countIntegerInArray = howMany(testingArray, currentIndexOfArray);

        if (countIntegerInArray == frequencyOfMode)
        {
            if (modeWeAreLookingFor > currentIndexOfArray)
            {
                modeWeAreLookingFor = currentIndexOfArray;
            }
        }

        else if (countIntegerInArray > frequencyOfMode)
        {
            modeWeAreLookingFor = currentIndexOfArray;
            frequencyOfMode = countIntegerInArray;              
        }

    }  
    return modeWeAreLookingFor;
    }

public int howMany(int[] testingArray, int c)
{

    int howManyOfThisInt=0;
    for(int i=0; i < testingArray.length;i++)
    {
        if(testingArray[i]==c){
            howManyOfThisInt++;

        }
    }
    return howManyOfThisInt;
}


public static void main(String[] args)
{
    new TheMode();
}
}

Comments

0

Glad you managed to solve it. As you will now see, there is more than one way to approach a problem. Here's what I meant by using a map

package util;

import java.util.HashMap;
import java.util.Map;

public class MathUtil {

    public static void main(String[] args) {
        MathUtil app = new MathUtil();
        int[] numbers = {1, 1, 1, 2, 2, 2, 3, 4};
        System.out.println(app.getMode(numbers));
    }

    public int getMode(int[] numbers) {
        int mode = 0;
        Map<Integer, Integer> numberMap = getFrequencyMap(numbers);

        int highestCount = 0;

        for (int number : numberMap.keySet()) {
            int currentCount = numberMap.get(number);

            if (currentCount > highestCount) {
                highestCount = currentCount;
                mode = number;
            } else if (currentCount == highestCount && number < mode) {
                mode = number;
            }
        }

        return mode;
    }

    private Map<Integer,Integer> getFrequencyMap(int[] numbers){
        Map<Integer, Integer> numberMap = new HashMap<Integer, Integer>();

        for (int number : numbers) {
            if (numberMap.containsKey(number)) {
                int count = numberMap.get(number);
                count++;
                numberMap.put(number, count);
            } else {
                numberMap.put(number, 1);
            }
        }

        return numberMap;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.