Reputation: 151
I want to sort the letters from user input and print out how many of each letter there is in the string from the user. This is what I have so far and i would like to know if this is the right way to do it. I am relatively new to java so please keep things s simple as possible. Ive made a few adjustments to my code upon the suggestions that I use loops instead of large amounts of if else constructs. This is what I have:
public class Assignment9
{
public static void main( String [] args )
{
String user_string = Input.getString( "Please enter a string" );
int length = user_string.length();
int char_number = 1;
int alphabet[] = new int[26];
for( int repeats = 0 , repeats <= length , repeats++ )
{
char letter = user_string.charAt( char_number );
char to_be_tested = Character.toLowerCase( letter );
int subscript = 0;
for(int letter_number = 97 , letter_number <= 122 , letter_number++ )
{
char tester = (char) letter_number;
if( to_be_tested == tester )
{
alphabet[subscript]++;
subscript++;
}
}
char_number++;
}
display( alphabet );
}
public static void display( int alphabet[] )
{
int letter = 65;
for( int a = 0; a < alphabet.length; a++ )
{
char character = ( char )letter;
System.out.println ( "letter " + character + " count is " + alphabet[a] );
letter++;
}
}
}
test.java:9: error: ';' expected
for( int repeats = 0 , repeats <= length , repeats++ )
^
test.java:9: error: illegal start of expression
for( int repeats = 0 , repeats <= length , repeats++ )
^
test.java:9: error: ';' expected
for( int repeats = 0 , repeats <= length , repeats++ )
^
test.java:9: error: illegal start of expression
for( int repeats = 0 , repeats <= length , repeats++ )
^
test.java:9: error: ')' expected
for( int repeats = 0 , repeats <= length , repeats++ )
^
test.java:9: error: illegal start of expression
for( int repeats = 0 , repeats <= length , repeats++ )
^
test.java:14: error: ';' expected
for(int letter_number = 97 , letter_number <= 122 , letter_number++ )
^
test.java:14: error: illegal start of expression
for(int letter_number = 97 , letter_number <= 122 , letter_number++ )
^
test.java:14: error: ';' expected
for(int letter_number = 97 , letter_number <= 122 , letter_number++ )
^
test.java:14: error: illegal start of expression
for(int letter_number = 97 , letter_number <= 122 , letter_number++ )
^
test.java:14: error: ')' expected
for(int letter_number = 97 , letter_number <= 122 , letter_number++ )
^
test.java:14: error: illegal start of expression
for(int letter_number = 97 , letter_number <= 122 , letter_number++ )
^
12 errors
Upvotes: 3
Views: 2184
Reputation: 6207
Using Java 8 Streams
String data = "some letters to count";
Stream.of(data.split("(?!^)"))
.collect(Collectors.groupingBy(Function.identity(), TreeMap::new, Collectors.counting()))
.forEach((key, value)->System.out.println(key+": "+value));
And here is the explanation:
First we split the data in one letter strings using a regular expression: data.split("(?!^)")
; and we obtain an array of String
's.
0 = "s"
1 = "o"
2 = "m"
3 = "e"
4 = " "
5 = "l"
6 = "e"
7 = "t"
8 = "t"
9 = "e"
10 = "r"
11 = "s"
12 = " "
13 = "t"
14 = "o"
15 = " "
16 = "c"
17 = "o"
18 = "u"
19 = "n"
20 = "t"
We create a Stream
from the said array: Stream.of(data.split("(?!^)"))
We do all the sorting and counting in this step using a groupingBy
Collector
and passing a TreeMap
(a SortedMap
implementation that will keep MapEntry
's sorted by key): .collect(Collectors.groupingBy(Function.identity(), TreeMap::new, Collectors.counting()))
.
The result of this step is a sorted TreeMap
with distinct single character String
's as keys and the count of this character as value.
0 = {TreeMap$Entry@755} " " -> "3"
1 = {TreeMap$Entry@756} "c" -> "1"
2 = {TreeMap$Entry@757} "e" -> "3"
3 = {TreeMap$Entry@758} "l" -> "1"
4 = {TreeMap$Entry@759} "m" -> "1"
5 = {TreeMap$Entry@760} "n" -> "1"
6 = {TreeMap$Entry@761} "o" -> "3"
7 = {TreeMap$Entry@762} "r" -> "1"
8 = {TreeMap$Entry@763} "s" -> "2"
9 = {TreeMap$Entry@764} "t" -> "4"
10 = {TreeMap$Entry@765} "u" -> "1"
Finally we print the result: .forEach((key, value)->System.out.println(key+": "+value));
Upvotes: 0
Reputation: 159
The thing is YOU are doing all of the work. What you need to do is make the COMPUTER work. All those printing statements take lots of copy pasting for no good reason. Hence using loops is a much more efficient way. And since you already know loops you could have come up with this solution-
import java.io.*;
public class experiments {
public static void main(String[] args) throws IOException {
//Scanner sc=new Scanner(System.in);
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int i,j;
char chr;
int len,count=0;
System.out.println("Enter text-->");
String str=br.readLine();
str=str.toUpperCase();
len=str.length();
for(i='A';i<='Z';i++)
{
for(j=0;j<len;j++)
{
chr=str.charAt(j);
if(chr==i)count++;
}
System.out.println((char)i+"-->"+count);
count=0;
}
}
}
Upvotes: 2
Reputation: 520968
I would much rather use a map here to store the counts of each of the letters:
Map<Character, Integer> letterMap = new HashMap<>();
String userString = Input.getString( "Please enter a string" );
for (int i=0; i < userString.length(); ++i) {
char letter = userString.charAt(i);
Integer value = letterMap.get(letter);
letterMap.put(letter, value == null ? 1 : value.intValue() + 1);
}
for (Map.Entry<Character, Integer> entry : letterMap.entrySet()) {
System.out.println("Letter '" + entry.getKey() + "' appeared " + entry.getValue() + " times.");
}
As @Stephank pointed out, this solution will not print any summary stats for letters which do not appear at all in the input. If you want to print stats for all letters, even if they do not appear, you could seed the map with the following code:
for (char letter = 'a'; letter <= 'z'; ++letter) {
letterMap.put(letter, 0);
}
Upvotes: 1
Reputation: 2371
Here is a simpler way to count letters, ignoring case:
final int[] chars = new int[26];
for (char c : value.toLowerCase().toCharArray()) {
if ((c >= 'a') && (c<= 'z')) {
chars[c - 'a']++;
}
}
Demo: https://repl.it/CmYR/0
Upvotes: 2
Reputation: 86
A simpler approach would be to use the map data structure. It stores (key, value) pairs. In your case the key would be the letter, and the value would be an integer representing the count. So when you encounter say, an 'a' you do yourMap.get('a')
and increment the value paired with that key.
Here you can read about maps in java: https://docs.oracle.com/javase/7/docs/api/java/util/Map.html
Upvotes: 1