2

I need help on this problem:

Write a method mostFrequentDigit that returns the digit value that occurs most frequently in a number. Example: The number 669260267 contains: one 0, two 2s, four 6es, one 7, and one 9. mostFrequentDigit(669260267) returns 6. If there is a tie, return the digit with the lower value. mostFrequentDigit(57135203) returns 3.

This is the code I have now, but it doesn't work:

public static int mostFrequentDigit(int num)
{
int largestCount = 0;
int currentCount = 0;
String num0 = Integer.toString(num)
 String mostFrequent = num0.substring(0,1);

for (int x = 0; x < num0.length(); x++)
{
        if (num0.substring(x,x+1).equals(mostFrequent))
        {
            currentCount++;
        }
        if (currentCount > largestCount)
        {
           largestCount = currentCount;
           mostFrequent = num0.substring(x,x+1);
        }
}
    return mostFrequent;

}
cc123
  • 37
  • 2

4 Answers4

2

You're going to have to keep track of the counts of all digits (e.g. in an array or Map) and get the result after you tallied all digits.

Here's an approach using an array:

public class MyClass {
    public static int mostFrequentDigit(int num) {
        int n = Math.abs(num);
        int digit = 0;
        int max = 0;
        int[] counts = new int[10];

        while (n != 0) {
            counts[n % 10]++;
            n /= 10;
        }

        for (int i = 0; i < counts.length; i++) {
            if (counts[i] > max) {
                digit = i;
                max = counts[i];
            }
        }

        return digit;
    }
    
    public static void main(String args[]) {
      System.out.println(mostFrequentDigit(57135203));
    }
}

This snippet uses a combination of modulo and integer division operations to get the separate digits, and for each digit increments the corresponding counter in an array. After everything is tallied, it traverses the array to find the digit with the highest counter.

Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
  • Hi! Thanks a lot for your help. Could you please clarify for me what you are doing in the while-loop? What’s the purpose? And why are you doing n%10, why not just n? Thanks! – cc123 Nov 30 '20 at 08:48
  • `n % 10` will give you the number's last digit. Let's say, for example, that that digit is `3`. Then `counts[n % 10]++` translates into `counts[3]++`, which means that the value of the fourth element in the array will be incremented. At the end of the while loop, the array will contain counter values for all digits from 0 to 9. – Robby Cornelissen Nov 30 '20 at 08:54
0

There are some logical errors in your code. Provide a simple and short code to do this as below.

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

        public static int mostFrequentDigit(int num) {

        Map<String, Integer> map = new HashMap<String, Integer>();

        for (int i = 0; i < 10; i++) {
            String digit = String.valueOf(i);
            map.put(digit, StringUtils.countMatches(String.valueOf(num), digit));
        }

        Comparator<Map.Entry<String, Integer>> byValue = Map.Entry.comparingByValue();
        Map.Entry<String, Integer> maxEntry = Collections.max(map.entrySet(), byValue);

        return Integer.parseInt(maxEntry.getKey());
    }
  • 1
    Does this satisfy the "If there is a tie, return the digit with the lower value" condition? Also, if you use an external library, it might be better to specify where that library can be obtained. – Robby Cornelissen Nov 30 '20 at 07:56
  • Of course this satisfy the "If there is a tie, return the digit with the lower value" condition. Thanks for reminding to specify where that library can be obtained. The package java.util can be obtained from https://docs.oracle.com/javase/8/docs/api/java/util/package-summary.html and it is a common-used library in Java language. – Winnie Lin Dec 02 '20 at 02:50
  • *Of course this satisfy the "If there is a tie, return the digit with the lower value" condition.* I don't see how. The map is unordered. Your `maxEntry` will just contain the entry with the highest value that was last encountered. And I'm not talking about the `java.util` package. That's part of the JDK. I'm talking about the Apache Commons library that you're using. – Robby Cornelissen Dec 02 '20 at 02:59
  • To update org.apache.commons.lang3 can be finded here https://commons.apache.org/proper/commons-lang/download_lang.cgi – Winnie Lin Dec 02 '20 at 05:18
  • Thanks for reply Update org.apache.commons.lang3 can be finded here https://commons.apache.org/proper/commons-lang/download_lang.cgi Collections.max will find out the mostFrequentDigit and the lower value (not last encountered) – Winnie Lin Dec 02 '20 at 05:25
  • *"Collections.max will find out the mostFrequentDigit and the lower value (not last encountered)"* **No, it will not.** You're comparing **unordered** map entries by value. Why would it return the lowest key? Sometimes it will, sometimes it won't, but it's in no way guaranteed. – Robby Cornelissen Dec 02 '20 at 05:50
  • I mean, In the beginning, I put this map in order, so Collections.max find out the mostFrequentDigit must be the lower value – Winnie Lin Dec 02 '20 at 07:00
  • I'll repeat in one more time: entries in a `HashMap` are **unordered**. From the [javadoc](https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html): *"This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time."* – Robby Cornelissen Dec 02 '20 at 07:32
  • If you want a guaranteed order, use a `LinkedHashMap` or a `TreeMap` instead. See also [this question](https://stackoverflow.com/questions/2144776/is-the-order-of-values-retrieved-from-a-hashmap-the-insertion-order). – Robby Cornelissen Dec 02 '20 at 07:46
0

Seems like school assignment problem. Your teacher definitely wants you to learn recursion.

So, collect data into array of size 10 (if you are computing for base 10 - you may do that same for base 16 for example)

Write recursive function (function which calls itself as long as it necessary ) which takes last digit of a number (modulo 10 in case of decimal digits) and passes rests of the number ( divided by 10, but as integer ) to next invocation of itself ( in case it is bigger than 0 )

After your recursion is terminated you have an array with counts for digits. Just process it with for loop and find index with maximal value

Konstantin Pribluda
  • 12,329
  • 1
  • 30
  • 35
0

Here you can do by this java8 approach :

public static int mostFrequentDigit(int num){
    Map<String, Long> collect = Integer.toString(num).chars().mapToObj(c -> (char) c).map(String::valueOf)
            .collect(groupingBy(Function.identity(), counting()));
    long maxCount = collect.values().stream().reduce(Math::max).orElse(0L);
    return collect.entrySet().stream().filter(a -> a.getValue() == maxCount)
            .map(a -> Integer.parseInt(a.getKey())).reduce(Math::min).orElse(null);
}
Mohsen R. Agdam
  • 364
  • 3
  • 12