There is something that doesn't quite make sense to me. Why does this:
public static int[] countNumbers(String n){
int[] counts = new int[10];
for (int i = 0; i < n.length(); i++){
if (Character.isDigit(n.charAt(i)))
counts[n.charAt(i)]++;
}
return counts;
}
bring up an ArrayOutOfBounds error while this:
public static int[] countNumbers(String n){
int[] counts = new int[10];
for (int i = 0; i < n.length(); i++){
if (Character.isDigit(n.charAt(i)))
counts[n.charAt(i) - '0']++;
}
return counts;
}
does not? The only difference between the two examples is that the index for counts is being subtracted by zero in the second example. If I'm not mistake, shouldn't the first example display correctly since the same value is being checked?
Here are the value being passed for the two methods:
System.out.print("Enter a string: ");
String phone = input.nextLine();
//Array that invokes the count letter method
int[] letters = countLetters(phone.toLowerCase());
//Array that invokes the count number method
int[] numbers = countNumbers(phone);
This is the problem:
counts[n.charAt(i)]++;
n.charAt(i)
is a character, which will be converted to an integer. So '0' is actually 48, for example... but your array only has 10 elements.
Note that the working version isn't subtracting 0 - it's subtracting '0', or 48 when converted to an int
.
So basically:
Character UTF-16 code unit UTF-16 code unit - '0'
'0' 48 0
'1' 49 1
'2' 50 2
'3' 51 3
'4' 52 4
'5' 53 5
'6' 54 6
'7' 55 7
'8' 56 8
'9' 67 9
The code is still broken for non-ASCII digits though. As it can only handle ASCII digits, it would be better to make that explicit:
for (int i = 0; i < n.length(); i++){
char c = n.charAt(i);
if (c >= '0' && c <= '9') {
counts[c - '0']++;
}
}
See more on this question at Stackoverflow