patternjavaMinor
Counting characters
Viewed 0 times
characterscountingstackoverflow
Problem
I'm a beginner at coding, and I am looking to improve the structure of how I write code and will take any tips. Posted a simple program that takes your name as input, then runs the string through a switch statement to print out how many of each character your name has, as well as any spaces and symbols.
```
package practice;
import java.util.Scanner;
public class counter {
public static void main(String[] args) {
Scanner data = new Scanner(System.in);
String name;
System.out.println("Enter name");
name = data.nextLine();
int len = name.length();
int ch = 0;
int charCount = 0;
int space = 0;
int symbols = 0;
int a = 0,b = 0,c = 0,d = 0,e = 0,f = 0,g = 0,h = 0,i = 0,j = 0,k = 0,l = 0,m = 0;
int n = 0,o = 0,p = 0,q = 0,r = 0,s = 0,t = 0,u = 0,v = 0,w = 0,x = 0,y = 0,z = 0;
for (int in = 0;in 0){
System.out.println("There are ("+a+"-As) in your name");
}
if (b > 0){
System.out.println("There are ("+b+"-Bs) int your name");
}
if (c > 0){
System.out.println("There are ("+c+"-Cs) int your name");
}
if (d > 0){
System.out.println("There are ("+d+"-Ds) int your name");
}
if (e > 0){
System.out.println("There are ("+e+"-Es) int your name");
}
if (f > 0){
System.out.println("There are ("+f+"-Fs) int your name");
}
if (g > 0){
System.out.println("There are ("+g+"-Gs) int your name");
}
if (h > 0){
System.out.println("There are ("+h+"-Hs) int your name");
}
if (i > 0){
System.out.println("There are ("+i+"-Is) int your name");
}
if (j > 0){
System.out.println("There are ("+j+"
```
package practice;
import java.util.Scanner;
public class counter {
public static void main(String[] args) {
Scanner data = new Scanner(System.in);
String name;
System.out.println("Enter name");
name = data.nextLine();
int len = name.length();
int ch = 0;
int charCount = 0;
int space = 0;
int symbols = 0;
int a = 0,b = 0,c = 0,d = 0,e = 0,f = 0,g = 0,h = 0,i = 0,j = 0,k = 0,l = 0,m = 0;
int n = 0,o = 0,p = 0,q = 0,r = 0,s = 0,t = 0,u = 0,v = 0,w = 0,x = 0,y = 0,z = 0;
for (int in = 0;in 0){
System.out.println("There are ("+a+"-As) in your name");
}
if (b > 0){
System.out.println("There are ("+b+"-Bs) int your name");
}
if (c > 0){
System.out.println("There are ("+c+"-Cs) int your name");
}
if (d > 0){
System.out.println("There are ("+d+"-Ds) int your name");
}
if (e > 0){
System.out.println("There are ("+e+"-Es) int your name");
}
if (f > 0){
System.out.println("There are ("+f+"-Fs) int your name");
}
if (g > 0){
System.out.println("There are ("+g+"-Gs) int your name");
}
if (h > 0){
System.out.println("There are ("+h+"-Hs) int your name");
}
if (i > 0){
System.out.println("There are ("+i+"-Is) int your name");
}
if (j > 0){
System.out.println("There are ("+j+"
Solution
try-with-resourcesSince Java 7, you should use
try-with-resources on your Scanner instance for safe and efficient handling of the underlying I/O resource (i.e. System.in).Data structures
As daunting as it may sound, this is actually an important concept to grasp for beginners. As pointed out by others, there is code duplication, and that is bad because As pointed out by others, there is code duplication, and that is bad because As pointed out by others, there is code duplication, and that is bad becuase As pointed out by others, there is code duplication, and that is bad because As pointed out by others, there is code duplication, and that is bad because I wonder if you realized the third because had a typo.
Even though Java doesn't let you reference undeclared variable names by accident, typos such as using the wrong variable names (interchanging
m and n perhaps?), numbers or operators may still allow the code to compile; that is when bugs sneak into your codebase and your 2:47 am coding nightmares.The point here is, instead of using upwards of 28 standalone variables (
a...z, spaces and symbols) to represent each counter, you should be using an array for starters, and eventually progress to Collections or even a
Stream-based processing approach (which I'm simply offering as links here).For example, if you are only interested in counting for
a...z, spaces and symbols, you need an int[] array with 28 elements:int[] counter = new int[28];Next, think about 'converting' each desired condition (whether the character is
a, b... a space or a symbol) into a 'place' in the array, i.e. the index. For example, you can count as in index 0, bs in index 1 and so on (ignoring case sensitivity for now):// inside a loop, assume input has been sanitized to all lower case
char current = input.charAt(i);
if (current >= 'a' && current '9') {
counter[27]++;
}This is a simplified implementation, and there's definitely room for improvement for the condition checking, such as using the range of
Character methods to test for whitespace or digits.The other major benefit to using an array is that you can loop through it too:
String values = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i 0) {
String value = i 1) {
value += i < 26 ? "'s" : "s";
}
System.out.println("There are " + counter[i] + value + " in the input");
}
}Beats having to copy-paste an
if-condition 28 times. :)Bug
Wells...
if(name.charAt(ch) == '0' && name.charAt(ch) == '1' && name.charAt(ch) == '2' ) {
// ...
}There is a bug here as the whole condition will never be
true due to the usage of &&. What you are looking for here is ||, i.e. if character == '0' OR character == '1' OR character == '2'.Program flow
if(name.charAt(ch) == '9' ) {
System.out.println("ERROR: NUMBERS NOT ALLOWED");
System.out.println("EXITING APPLICATION");
System.exit(1);
}Causing your program to inexplicably
exit(1) when encountering a number is a particularly harsh way of handling errors... (Very) often, you will want to make it easier to recover from errors and retry wherever possible. For example, if you want to consider any input with numbers in them as wrong and re-prompt for a fresh input, you can do something like this:private static boolean hasDigits(String input) {
// test for digits here, return true if there are
}
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
String input = scanner.nextLine();
while (hasDigits(input)) {
System.out.println("No numbers please.");
input = scanner.nextLine();
}
// do something with input
}
}Or alternatively, wrap the validation into its own method:
private static String getInput(Scanner scanner) {
String input = scanner.nextLine();
while (hasDigits(input)) {
System.out.println("No numbers please.");
input = scanner.nextLine();
}
return input;
}
// refactored main()
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
String input = getInput(scanner);
// do something with input
}
}Formatting
Another useful advice for beginners is to standardize on the code formatting style. Currently, your code is already lengthy enough without the extra empty lines, and your bracing (
{...}) is quite inconsistent.There are different schools of thoughts about 'paragraphing' code into nice-looking blocks with empty lines as separators, and the one I think is arguably more practical is if you have to resort to this, the method is just too long (like your
main() method now). Favor smaller 'bite-size' methods that more expressively captures a processing 'step', rather than creating monolithic ones that do everything.As for braces, it's recommended not to skim
Code Snippets
int[] counter = new int[28];// inside a loop, assume input has been sanitized to all lower case
char current = input.charAt(i);
if (current >= 'a' && current <= 'z') {
counter[current - 'a']++;
} else if (current == ' ') {
counter[26]++; // we start from 0, so index 26 is the 27th place, after 'z'
} else if (current < '0' || current > '9') {
counter[27]++;
}String values = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < counter.length; i++) {
if (counter[i] > 0) {
String value = i < 26 ? values.charAt(i) : i == 26 ? "space" : "symbol";
if (counter[i] > 1) {
value += i < 26 ? "'s" : "s";
}
System.out.println("There are " + counter[i] + value + " in the input");
}
}if(name.charAt(ch) == '0' && name.charAt(ch) == '1' && name.charAt(ch) == '2' ) {
// ...
}if(name.charAt(ch) == '9' ) {
System.out.println("ERROR: NUMBERS NOT ALLOWED");
System.out.println("EXITING APPLICATION");
System.exit(1);
}Context
StackExchange Code Review Q#113894, answer score: 6
Revisions (0)
No revisions yet.