3

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++;
    }
}
}

I'm getting these errors

Compilation errors:

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
stephank
  • 91
  • 5
justin
  • 169
  • 6
  • Has your instructor taught you what a loop is? Could you try using one? Also you should fix the syntax errors in your code, StackOverflow doesn't allow simple syntax questions like that. – markspace Aug 12 '16 at 08:07
  • Upvote just for awesome if/else statement – Paolo Forgia Aug 12 '16 at 08:08
  • If by "awesome" you mean horrifying. – markspace Aug 12 '16 at 08:08
  • 1
    @markspace awesome effort for an horrifying code – Paolo Forgia Aug 12 '16 at 08:09
  • 1
    Horrifying indeed. OP I recommend that you look at the usage of Arrays, your code is so bloated and what you're trying to do can easily be accomplished with prebuilt functions like `Array.indexOf(element)`. You could use that to match a letter in a word with the index of an array and increment that index for instance. – px06 Aug 12 '16 at 08:10
  • For your answer I would suggest to take a look at this: [How can I sort a List alphabetically?](http://stackoverflow.com/questions/708698/how-can-i-sort-a-list-alphabetically) and this: [Find duplicate characters in a String and count the number of occurances using Java](http://stackoverflow.com/questions/13119926/find-duplicate-characters-in-a-string-and-count-the-number-of-occurances-using-j). I hope those will help – Paolo Forgia Aug 12 '16 at 08:18
  • Found my problem. They were incorrect syntax in for loop and incorrect operators. – justin Sep 11 '16 at 21:07

5 Answers5

2

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

Olian04
  • 6,480
  • 2
  • 27
  • 54
Slimu
  • 2,301
  • 1
  • 22
  • 28
2

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;
    }
  }
}
N00b Pr0grammer
  • 4,503
  • 5
  • 32
  • 46
knightcube
  • 139
  • 1
  • 13
  • Can you please explain how this one works. I would really like to use some of the keywords you used here in later programs. – justin Aug 12 '16 at 16:54
  • The first thing is that we are taking a string input and converting it to uppercase(keep reading and u will understand why i did that :)... ). – knightcube Aug 15 '16 at 06:16
1

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

bdvll
  • 86
  • 6
1

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);
}
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
0

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:

  1. 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"

  2. We create a Stream from the said array: Stream.of(data.split("(?!^)"))

  3. 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"

  4. Finally we print the result: .forEach((key, value)->System.out.println(key+": "+value));

Daniel Cerecedo
  • 6,071
  • 4
  • 38
  • 51