Zero0
Zero0

Reputation: 3

How do I make a program that counts the occurrence of each individual digit between 1 and 100?

I'm making a program that counts how many times each digit (0-9) occurs in each number between 1 to 100. At the end it will say something like:

The digit 0 showed up ____ times between 1-100
The digit 1 showed up ____ times between 1-100

and so forth.

This is what I have:

public class CountEachDigit {

    public static void main(String[] args) {

        int counter =0;

        int[] digit = new int[10];

        for (int i=1;i<=100;i++) {
    
            for (int j=0;j<=9;j++){
  
                try{
                    String a = String.valueOf(i);
                    String b = String.valueOf(j);
                    if (b.equals(a.charAt(0)))
                            counter++;
                            digit[j]=counter;
                } catch (Exception e){
                    continue;
                }

                try{
                    String a = String.valueOf(i);
                    String b = String.valueOf(j);
                    if (b.equals(a.charAt(1)))
                        counter++;
                        digit[j]=counter;
                } catch (Exception e){
                    continue;
                }

                try{
                    String a = String.valueOf(i);
                    String b = String.valueOf(j);
                    if (b.equals(a.charAt(2)))
                        counter++;
                        digit[j]=counter;
                } catch (Exception e){
                    continue;
                }
    
            }
        }

        for (int j =0;j<=9;j++){
            System.out.println("The number "+j+" appears "+digit[j]+" times between 1 - 100.");
        }
    }
}

I tried changing the charAt each digit to a String to count the occurrence using the try and catch. No dice so far.

Upvotes: 0

Views: 573

Answers (6)

Oleg Cherednik
Oleg Cherednik

Reputation: 18255

You do not need a string operations. You have to use x % 10 to get the last digit, and then x \= 10, to remove this last digit.

public class CountEachDigit {

    public static void main(String... args) {
        final int lo = 1;
        final int hi = 100;
        int[] digits = countDigits(lo, hi);

        for (int i = 0; i < 10; i++)
            System.out.format("The number %d appears %d times between %d - %d.\n", i, digits[i], lo, hi);
    }

    private static int[] countDigits(int lo, int hi) {
        int[] digits = new int[10];

        for (int i = lo; i <= hi; i++) {
            int val = i;

            do {
                digits[val % 10]++;
            } while ((val /= 10) > 0);
        }

        return digits;
    }

}

Demo:

The number 0 appears 11 times between 1 - 100.
The number 1 appears 21 times between 1 - 100.
The number 2 appears 20 times between 1 - 100.
The number 3 appears 20 times between 1 - 100.
The number 4 appears 20 times between 1 - 100.
The number 5 appears 20 times between 1 - 100.
The number 6 appears 20 times between 1 - 100.
The number 7 appears 20 times between 1 - 100.
The number 8 appears 20 times between 1 - 100.
The number 9 appears 20 times between 1 - 100.

Upvotes: 1

WJS
WJS

Reputation: 40057

You can do it using by streaming and collecting in a map.

  • allocate a map to hold the counts
  • stream the values from 1 to 100 inclusive
  • within mapMulti
    • get the last digit by using the remainder % operator
    • accept the digit and place on the stream
    • expose the next digit by dividing by 10
  • Now collect the digits in the map, creating a frequency count as they occur. Each digit will the the key and the value will be the count.
Map<Integer, Integer> counts = IntStream.rangeClosed(1, 100)
         .mapMulti((val, consumer) -> {
             while (val > 0) {
                 consumer.accept(val % 10);
                 val /= 10;
             }
         }).boxed()
         .collect(Collectors.toMap(i -> i, i -> 1, Integer::sum));

 counts.forEach((digit, count) -> System.out
               .println(digit + " occurs " + count + " times."));

prints

0 occurs 11 times.
1 occurs 21 times.
2 occurs 20 times.
3 occurs 20 times.
4 occurs 20 times.
5 occurs 20 times.
6 occurs 20 times.
7 occurs 20 times.
8 occurs 20 times.
9 occurs 20 times.

Upvotes: 0

JakeStud
JakeStud

Reputation: 41

Using strings:

for (int i = 1; i <= 100; i++) {
    String num = String.valueOf(i); 
    for(int j=0;j<num.length();j++){
//substracting 0 to get the integer value
        counts[num.charAt(j)-'0']++;
    }
}
for (int i = 0; i < 10; i++) {
    System.out.println("The digit " + i + " showed up " + counts[i] + " times between 1-100.");
}

Upvotes: 1

crissal
crissal

Reputation: 2657

Instead of converting a number to string and then loop over its digits, you can also take the remainder by 10, i.e., the last digit, and then divide the number by 10 to "shift" it to the right. For example, 45 % 10 == 5, and 45 / 10 == 4.

After you exit the while loop, your number is a single-digit number, so you have to count again that digit.

public class CountEachDigit {

    public static void main(String[] args) {

        int[] digits_count = new int[10];
        int min = 1;
        int max = 100;

        for (int i = min; i <= max; ++i) {
            int number = i;

            while (number > 9) {
                int last_digit = number % 10;
                digits_count[last_digit] += 1;

                number /= 10;
            }

            digits_count[number] += 1;
        }

        for (int i = 0; i < 10; i++) {
            int count = digits_count[i];
            System.out.println("Digit " + i + " appears " + count + " times in range [" + min + ", " + max + "]");
        }

    }
}

Upvotes: 1

Eritrean
Eritrean

Reputation: 16508

In case you or future readers want to see a stream approach, which I doubt, here's what I did just for fun: Stream over the range [1 - 100], convert and map to String, split each String at each charachter such that, for example "42" becomes a stream of "4" and "2", collect to map using digit as key and count of occurrence as value and finally print.

import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

// ...

public static void main(String[] args) {
    IntStream.rangeClosed(1, 100)
             .mapToObj(String::valueOf)
             .flatMap(s -> Arrays.stream(s.split("")))
             .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
             .forEach((k,v) -> System.out.printf("The digit %s showed up %d times between 1-100%n", k, v));
}

Upvotes: 1

queeg
queeg

Reputation: 9473

Have an array with int[10] to count the occurrences for each digit.

Then have a function that traverses a string and for each digit it finds increases the correct field in the array.

Then have a loop over numbers from 1 to 100 which converts that number to string and feeds it into the function.

Finally print the array values.

In code this may look like

public class Test {

    static int[] occurrences = new int[10];
    
    static void checkOccurrences(String s) {
        for (char c: s.toCharArray()) {
            if (Character.isDigit(c)) {
                occurrences[ c - '0' ]++;
            }
        }
    }
    
    public static void main(String[] args) {
        for (int i=1; i<=100; i++) {
            String s = String.valueOf(i);
            System.out.println("checking "+s);
            checkOccurrences(s);
        }
        System.out.println(Arrays.toString(occurrences));
    }
}

and it prints

checking 1
checking 2
checking 3
...
checking 99
checking 100
[11, 21, 20, 20, 20, 20, 20, 20, 20, 20]

Upvotes: 1

Related Questions