0

Hey all so here is the problem that I'm asked to solve:

Write a program that will read in a line of text and output a list of all the letters that occur in the text, along with the number of times each letter occurs. End the line with a period that serves as a sentinel value. The letters should be listed in alphabetical order when they are output. Use an array of base type int of length 26, so that each indexed variable contains the count of how many letters there are. Array indexed variable 0 contains the number of a’s, array indexed variable 1 contains the number of b’s and so forth. Allow both uppercase and lowercase letters as input, but treat uppercase and lowercase versions of the same letter as being equal.

Here is my code so far

import java.util.Scanner;
public class Letters {

public static void main(String[] args) {
    Scanner keyboard = new Scanner(System.in);

    int letter[] = new int[26];

    System.out.println("Enter in a list of letters");
    String s = keyboard.nextLine();
    String a = s.toUpperCase();
    System.out.println(a);
    for(int i = 0; i<s.length();i++){
        switch (a.charAt(i)){
            case 'A':letter[0]++;
                break;
            case 'B': letter[1]++;
                break;
            case 'C':letter[2]++;
                break;
            case 'D': letter[3]++;
                break;
            case 'E':letter[4]++;
                break;
            case 'F': letter[5]++;
                break;
            case 'G':letter[6]++;
                break;
            case 'H': letter[7]++;
                break;
            case 'I':letter[8]++;
                break;
            case 'J': letter[9]++;
                break;
            case 'K':letter[10]++;
                break;
            case 'L': letter[11]++;
                break;
            case 'M':letter[12]++;
                break;
            case 'N': letter[13]++;
                break;
            case 'O':letter[14]++;
                break;
            case 'P': letter[15]++;
                break;
            case 'Q':letter[16]++;
                break;
            case 'R': letter[17]++;
                break;
            case 'S':letter[18]++;
                break;
            case 'T': letter[19]++;
                break;
            case 'U':letter[20]++;
                break;
            case 'V': letter[21]++;
                break;
            case 'W':letter[22]++;
                break;
            case 'X': letter[23]++;
                break;
            case 'Y':letter[24]++;
                break;
            case 'Z': letter[25]++;
                break;
            }
        }
    }
}

Clearly, I'm not done. So I'm solving this problem one step at a time and the problem I'm having at the moment is to find a way to display the number of times all the letters appeared in the user input without displaying the letters that were not inputted. My current idea is use a bunch of if statements but I know that will get messy super quick.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578

3 Answers3

1

In order to avoid the multiple if statements you can use something as simple as :

int index = a.charAt(i) - 'A';
letter[index]++;

You might also want to consider the possibility of the string having small alphabets & other special characters.

For displaying the count of the letters :

for(int index = 0 ; index < letter.length ; ++index)
{
    if(letter[index] > 0 )
    {
        char ch = (char) ('A' + index);
        System.out.pritln("Char : " + ch + " , occurence : " + letter[i]);
    }
}
Kakarot
  • 4,252
  • 2
  • 16
  • 18
1

You should key into the more general idea of a Map. In this case, a Map<char, int>.

Map<Char, Integer> frequency = new Map<Char, Integer>();
for(int i = 0; i<s.length();i++) {
    Char c = s.charAt(i).toLowerCase();
    if (frequency.containsKey(c)) {
      frequency.put(c, frequency.get(c)++);
    } else {
      frequency.put(c, 1);
    }
}

What are the advantages of this approach? To begin with, indexing a particular character at a particular location in an array is arbitrary. What you're really doing is counting characters. This lets you look up a character count with frequence.get('x'), where x is whatever character you're looking for, or even a variable containing a character. Secondly, a map can handle any arbitrary number of characters - you don't have to plan this out ahead of time. New characters in this scheme are just added into the map.

Because this is a more general solution, you can further leverage the Java API to do the following:

frequencey.values().toArray();

This maintains the data integrity of your core object while allowing you to output it as an arbitrary array. The method values() returns a Collection object. Note that Java Collections allow all sorts of fun sorting options; by the value of the key, by the frequency (or value of the value in the Map's key->value pair), or any arbitrary setup you can imagine.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • 1
    OP's assignment is to use an array. Although your suggestion is the better solution for an actual program, it might not be acceptable for OP to hand in (probably has not covered `Maps`, among other things). – Reinstate Monica -- notmaynard Apr 14 '14 at 21:33
  • I'll grant that the solution is orthogonal to the assignment. However, this is flat out a better way to do it. – Nathaniel Ford Apr 14 '14 at 21:37
0

Try the following as your main method:

public static void main(String[] args) {

    Scanner keyboard = new Scanner(System.in);

    int letterCount[] = new int[26];

    System.out.println("Enter in a list of letters");
    String inputString = keyboard.nextLine();
    char[] charArr = inputString.toUpperCase().toCharArray();
    System.out.println(charArr);
    for(char ch : charArr) {
        if(ch >= 'A' && ch <='Z') {
            letterCount[ch-'A']++;
        }
    }

    for(int i=0; i < letterCount.length; i++) {
        if(letterCount[i] > 0) {
            System.out.println(String.format("%c - %d", (i+'A'), letterCount[i]));
        }
    }

}