4

I'm doing college course exercises, and I just can't seem to do one of them. We're asked to enter a number, like 1975333, and the program is supposed to return "Number 3 appears 3 times". It's basically supposed to tell you the mode of the number.

This is what I have, but I can't seem to make it to work, no matter what I try:

import static java.lang.System.*;
import static javax.swing.JOptionPane.*;
import static java.lang.Math.*;

public class Oblig5 {

    public static void main(String[] args) {

        int tall = input_tall();
        int siffervekt = 0;
        int t_siffervekt = 0;

        int lengde = (int) (Math.log10(tall) + 1);

        for (int siffer = 0; siffer == lengde; siffer++) {
            System.out.println("Siffer = " + siffer);
                for (int x = 0; x < lengde; x++) {
                    int asiffer = (tall % 10);
                    System.out.println("Asiffer = " + asiffer);
                    if (asiffer == siffer) {
                        siffervekt++;
                        out.println(siffervekt);
                    }
                    tall = tall / 10; 
                }
            t_siffervekt = max(siffervekt, t_siffervekt);   
        }
    }

    private static int input_tall() {
        return Integer.parseInt(showInputDialog(null, "Skriv inn ønsket tall"));
    }

}
hata
  • 11,633
  • 6
  • 46
  • 69
TobiasS
  • 49
  • 2
  • 1
    What is "the mode of the number"? –  Mar 09 '15 at 13:06
  • Y'know, mean, median, mode? Basically, what number appears the most times – TobiasS Mar 09 '15 at 13:07
  • That's not the median. "In statistics and probability theory, the median is the number separating the higher half of a data sample, a population, or a probability distribution, from the lower half." What is your question? –  Mar 09 '15 at 13:12
  • `import static *` should be used with care, as it drops the class relating part of identifiers and can have great impact on the readability of the code. I recommend to remove your static import lines and replaces them to 'normal' imports. And please: Fix your indentation and use english identifiers. – Binkan Salaryman Mar 09 '15 at 13:13
  • Possible duplicate of [Write a mode method in Java to find the most frequently occurring element in an array](http://stackoverflow.com/questions/15725370/write-a-mode-method-in-java-to-find-the-most-frequently-occurring-element-in-an) – TNT Mar 09 '15 at 13:15
  • 2
    @LutzHorn: He didn't say it was the median. He said "mean, median, mode," which are all measures of average. He wants the mode. – michaelgulak Mar 09 '15 at 13:15
  • The mean and the median are not the same thing. –  Mar 09 '15 at 13:17
  • 3
    @LutzHorn: He never... said... that he wanted... to find... the median. Nobody ever said they were the same thing. Please re-read the comment. – michaelgulak Mar 09 '15 at 13:20
  • 1
    But..the plural of medium is media, not mean. –  Mar 09 '15 at 13:26
  • You guys. Everyone should know this by now. Mean, median, and mode are 3 DIFFERENT types of averages. We learn them all, and mode is the one he wants. Stop being so stupid. – mbomb007 Mar 09 '15 at 13:28
  • Pay attention, people - finally the clever person has showed up. (Where were you 25 minutes ago when we needed you?) –  Mar 09 '15 at 13:33

8 Answers8

0

With counting each specific digit, I feel it would be easier to keep the number as a String (remove Integer.parseInt()) then count each char in a HashMap by value and count. For example:

public int[] getMostCommon(String numbers){ //Returning int[] for [0] = digit and [1] = frequency
    HashMap<Character, Integer> digits = new HashMap<Character, Integer>();
    for (char myChar : numbers.toCharArray()){
        int count = digits.getOrDefault(myChar, 0);
        digits.put(myChar, count+1); //getOrDefault is Java 8+ only, see below if running earlier versions
    }
    int[] returnValue = new int[] {0, 0};
    for (int i = 0; i <= 9; i++){ //Loop through each digit to see which is most frequent
        if (digits.get((char) i+48) > returnValue[1]){ //+48 for ASCII conversion to char, see http://www.asciitable.com/
            returnValue[0] = i;
            returnValue[1] = digits.get((char) i+48);
        }
    }
    return returnValue;
}

If you're not running Java 8, you'll need to use the following code in place of getOrDefault:

int count = 0;
if (digits.containsKey(myChar)){
    count = digits.get(myChar);
}
llamositopia
  • 724
  • 5
  • 11
0

One possible straight forward solution snippet to find the digit with the highest count.
This snippet is not supposed to provide a solution for all edge cases. It's rather to show a possible way to find the solution.

// the input number
int input = 1975333;

// check the last digit and increment the count for this digit
int[] digits = new int[10];
while (input > 0) {
    digits[input % 10]++;
    input /= 10;
}

// find the digit with the highest count
int maxCount = 0;
int maxIdx = 0;
for (int i = 0; i < digits.length; i++) {
    if (digits[i] > maxCount) {
        maxCount = digits[i];
        maxIdx = i;
    }
}
System.out.printf("max digit: %d  count: %d%n", maxIdx, maxCount);
SubOptimal
  • 22,518
  • 3
  • 53
  • 69
0

Just keep a running total of every digit and then look for the greatest one. Use val itself to control the loop to avoid any miscalculations of the length of the value being analysed.

    public Mode(long val) {
        long[] count = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        while(val > 0) {
            int digit = (int)(val % 10L);
            count[digit] ++;
            val /= 10;
        }
        int mode = 0;
        long maxVal = 0;
        for(int i = 0; i < 10; i++) {
            if(count[i] > mode) {
                mode = i;
                maxVal = count[i];
            }
        }
        System.out.println("Number " + mode + " appears " + maxVal + " times");
    }
Neil Masson
  • 2,609
  • 1
  • 15
  • 23
0

You can do it using a new Array[10] in which you will save the frequency of each digit [0-9] and then return the max value of this array:

public int mostFrequentVlaue(int number){
   String num=number.toString();
    int[] freqArray=new int[10];
   // initialize the frequency array with zeros
   for(int k=0;k<9;k++){
        freqArray[k]=0;
   }

   //loop throught our number string and count frequency of each digit
   for(int i=0;i<num.length();i++){
     switch (num.charAt(i)) {
        case '0':  freqArray[0]++;
                 break;
        case '1':  freqArray[1]++;
                 break;
        case '2': freqArray[2]++;
                 break;
        case '3':  freqArray[3]++;
                 break;
        case '4':  freqArray[4]++;
                 break;
        case '5':  freqArray[5]++;
                 break;
        case '6':  freqArray[6]++;
                 break;
        case '7':  freqArray[7]++;
                 break;
        case '8':  freqArray[8]++;
                 break;
        case '9':  freqArray[9]++;
                 break;
    }
  }
  int max=freqArray[0];
  int freq=0;
  for(int j=1;j<9;j++){
        if (freqArray[j] > max) {
            max = freqArray[j];
            freq=j;
        }
   }
  return freq;
}

And that's all what you need.

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
0
public static void getMode(int number){
    int[] countArray = new int[10];
    while(number > 0){
        //We take a single number from the number using modulo
        int n = number%10;
        countArray[n]++;
        //We remove the number we already used.
        number= number/10;
    }
    //Count cannot possibly be less than -1
    int max = -1;
    for(int i = 0; i< 10; i++){
        //Checking which number occurs the most and updates max
        if(countArray[i] > max)
            max = countArray[i];
    }
    System.out.println("Number " + getNumber(countArray, max) + " appears " + max + " times");
}

//Helping method I made in order to get which number was found the most
public static int getNumber(int [] array, int max){
    //Simply the array element which contained max is the element
    //that occured the most.
    for(int i = 0; i < array.length; i++){
        if(array[i] == max)
            return i;
    }
    return -1;
}

When counting numbers an array from 0-9 helps a lot because it covers the range of all possible numbers. So let me walk you through my code. A user enters a number, suppose it is 123455.

You enter the while loop and that number is indeed greater than 0. Using % on the number gives you 5. countArray[5]++ means that countArray at position 5 increases by 1. Afterwards, the number should be divided by 10 in order to get rid of the number you have already used, and it is updated.

Now your countArray looks like this {0, 0, 0, 0, 0, 1, 0, 0, 0, 0}. Your number is now 12345, which is still greater than 0, you reenter the loop. Using % again gives you 5. countArray[5] which is now 1 is incremented by 1 again.

Your countArray looks like {0, 0, 0, 0, 0, 2, 0, 0, 0, 0}. Your number is now 1234, which is still greater than 0, you reenter the loop. Using % gives you 4. countArray[4] is incremented. Your countArray looks like {0, 0, 0, 0, 1, 2, 0, 0, 0, 0}. So on and so forth until there are no more numbers left to count, which in that case the array would look like {0, 1, 1, 1, 1, 2, 0, 0, 0, 0}.

The next for loop is about finding what was the maximum count found. It is straightforward, loops over the array and if it finds a number greater than max, max becomes that number. In this case max will eventually become 2.

Although we have found how many times the most counted number was counted, we still do not know what that number is i.e in my example, we know the most counted number was counted 2 times but we still do not know that it is a 5. Hence, the helper method I created finds which number was counted the most. It loops over the array, if the array at some position contains the maximum number of counts, then that has to be the number.

iskandarchacra
  • 358
  • 3
  • 7
0

I have given try to implement using map which is giving the correct output. Hope this might help you .. :)

package digit;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;

public class RecurringDigit {


public static void main(String args[]) throws IOException {
    try {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        char[] chars = str.toCharArray();
        //Created map for each digit
        final ConcurrentMap<Character, AtomicInteger> map = new  ConcurrentHashMap<>();
        for (char c : chars) {
            final char key = c;
            map.putIfAbsent(key, new AtomicInteger(0));
            map.get(key).incrementAndGet();
        }
        //To find max count of that digit
        Map.Entry<Character, AtomicInteger> maxEntry = null;

        for (Map.Entry<Character, AtomicInteger> entry : map.entrySet()) {

            if (maxEntry == null || entry.getValue().intValue() > maxEntry.getValue().intValue()) {
                maxEntry = entry;
            }
        }
        System.out.println("Number "+ maxEntry.getKey() + " appears " + maxEntry.getValue() +" times");
    } catch (Exception e) {
        e.printStackTrace();
    }

   }
 }
AKs
  • 1,727
  • 14
  • 18
0

Try this:

public class RecurringDigit {
    public static void main(String args []) {
        //--------Change input--------\\
        int input = 1975333;
        //----------------------------\\

        int[] digits = toDigitArray(input);
        int[] counts = new int[10];

        int mode = 1;
        int modeAmount = 1;
        boolean isMode = false;

        for(int i = 0; i < digits.length; i++) {
            int digit = digits[i];
            counts[digit]++;

            if(modeAmount < counts[digit]) {
                modeAmount = counts[digit];
                mode = digits[i];
                isMode = true;
            }
        }

        if(isMode) {
            System.out.println("Number " + mode + " appears " + counts[mode] + " times.");
        } else {
            System.out.println("All numbers appear an equal amount of times.");
        }
    }

    public static int[] toDigitArray(int number) {
        String temp = Integer.toString(number);
        int[] output = new int[temp.length()];
        for (int i = 0; i < temp.length(); i++)
        {
            output[i] = temp.charAt(i) - '0';
        }

        return output;
    }
}

The code first turns the int into an int array called digits which contains all of the digits, each in a different index. Then an int array called counts is created to hold the amount of times a number occurs, each index representing a different number (example: counts[5] equals the amount of times 5 occurs). Then a for loop is used to update the counts array and update the mode if the current occurrence amount is the largest. The for loop also sets the isMode boolean to true the first time the mode is updated. Finally the mode (from the mode variable) and the amount of times that the mode occurs (from counts[mode]) are printed. Also, if the boolean isMode is true, a message is printed saying that there is no mode. I hope code this helped you a little bit.

Nolan
  • 175
  • 9
-1
for (int siffer=0; siffer==lengde; siffer++)

change to:

for (int siffer=0; siffer < lengde; siffer++)

because siffer is 0 at start and lengde is 7, so your for loop will never execute...

Tom
  • 16,842
  • 17
  • 45
  • 54
sgpalit
  • 2,676
  • 2
  • 16
  • 22