开发者

Find number of occurences of each digit in string

FYI. Another practice exercise that I'm stuck on. The problem is to find the number of occurences of each digit in a string. I feel like I'm pretty close, but I'm getting some whacky results. I'm a beginner, so please keep hints/help at my level if possible. Thanks!

Here is what I have so far:

import java.util.Scanner;

    public class Practice5 {
 public static void main(String[] args) {
  Scanner input= new Scanner(System.in);
  System.out.println("Enter a string");
  String s = input.next(开发者_运维知识库);

  int[] counts = countNumbers(s);

  String output = "";

  for (int i = 0; i < counts.length; i++) {
   if (counts[i] != 0)
                        {
           output += "Digit" + (char)('0' + i) + " appears " +
           counts[i] + ((counts[i] == 1) + " times\n");
                        }

           }

                System.out.print(output);
           }


 private static int[] countNumbers(String s) {
  int[] counts = new int[10];

  for(int i = 0; i < s.length(); i++) {
   if (Character.isDigit(s.charAt(i)));
   counts[s.charAt(i) - '0']++;
  }
  return counts;
 }
}

Ok. Now if I enter a string like "23 t5t6 u76u 232 g1"

I get:

2 appears 1 time
3 appears 1 time

This is obviously incorrect. It should be 2 appears 3 times, 3 occurs 2 times, 5 occurs 1 time, etc. Any help would be appreciated.


Your first problem is with the use of the Java scanner. If I am not mistaken, you are only reading the first substring up to the first space. You probably wanted to run over the entire string, so a scanner is not the right thing to use.

Once you get the entire string, you still have a problem. The major problem in your code is that in the line that reads

if (Character.isDigit(s.charAt(i)));

you have a semicolon at the end. As a result of this, the next line (where you update the values) is always executed. This is a problem because sometimes your character would not be a digit, so the index "character-'0'" could fall outside the 10 that you have defined. This should be caught by Java to create an exception. You're not seeing this exception because your code would only process the first "23"


remove the semicolon at the end of this statement:

if (Character.isDigit(s.charAt(i)));

Your coding style is causing you problems. If you would adopt some sensible conventions (e.g., consistent intending, braces around ALL blocks like if/else and for), you'd have no problem spotting this error.


In addition to the extra semi-colon that the others mentioned, your input contains space (" ") characters but you only read the first set of characters up to the whitespace. You could use a line like this to read a whole line of input instead:

String s = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)).readLine();

You'll either need to use a try/catch block or add 'throws java.io.IOException' to your method.


This is too long for a comment so I put this in a answer for I think it's interesting and not necessarily well known.

For the sake of completeness, it should be noted that I can enter a string that shall crash your program. You're assigning an int[] able to hold 10 integers, but you have to know that there are much much more than 10 digits amongst the Unicode Characters.

So your program shall throw an ArrayIndexOutOfBoundsException for a great many digits.

You can print all the characters that are digits according to Character.isDigit(...) using the following program (Character.isDigit(...) takes an int, so we loop trough all the positive ints):

  for (int i = 0; i < Integer.MAX_VALUE; i++) {
    if (Character.isDigit(i)) System.out.println(i + ": " + (char) i);
  }

On my Java version this returns 268 such digits (the actual number of digits can vary from one Java version to another, depending on the actual version of Unicode supported).

Note that isDigit(...) doesn't take a char, but an int, representing a Unicode codepoint.

48 is a digit: 0
49 is a digit: 1
50 is a digit: 2
51 is a digit: 3
52 is a digit: 4
53 is a digit: 5
54 is a digit: 6
55 is a digit: 7
56 is a digit: 8
57 is a digit: 9
1632 is a digit: ٠
1633 is a digit: ١
1634 is a digit: ٢
1635 is a digit: ٣
1636 is a digit: ٤
1637 is a digit: ٥
1638 is a digit: ٦
1639 is a digit: ٧
1640 is a digit: ٨
1641 is a digit: ٩
1776 is a digit: ۰
1777 is a digit: ۱
1778 is a digit: ۲
1779 is a digit: ۳
1780 is a digit: ۴
1781 is a digit: ۵
1782 is a digit: ۶
1783 is a digit: ۷
1784 is a digit: ۸
1785 is a digit: ۹
etc.


I will give you another simple algorithm that I created:

public class Ex95 {

    public static void main(String[] args) {
        int [] counts = count("1B2A2137455");
        for (int i = 0; i < counts.length; i++) {
            System.out.println("counts of [" + i + "] is: " + counts[i]);

        }

    }
    public static int[] count(String s){
        int [] counts = new int[10];
        char [] c = s.toCharArray();
        int counter = 0;
        for(int i=0;i<counts.length;i++){
            for(int j=0;j<c.length;j++){

                    if(Character.isDigit(c[j]) && i == Character.getNumericValue(c[j])){
                        counter++;

                }
            }
            counts[i] = counter;
            counter = 0;
        }
        return counts;
    }
}


you can use the below code to get the results instead of checking Character.isDigit function:-

public static void main(String[] args){
    int[] arr = {0,1,2,3,4,5,6,7,8,9};
    String str = "abc123456";
    HashMap<Integer,Integer> hm = new HashMap<Integer,Integer>();
    for (int i=0;i<10;i++){
        hm.put(arr[i], 0);
    }
    for (int i=0;i<str.length();i++){
        if(hm.containsKey(str.charAt(i) - '0')){
            hm.put(str.charAt(i) - '0', hm.get(str.charAt(i) - '0')+1);
        }
    }
    System.out.println(hm);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜