Question: I need to find an algorithm which counts the letters in any string (e.g. "cabababb") and the output must be in a alphabetical manner(e.g. a: 3, b: 4, c:1 etc.) . There is no need to distinguish between upper and lower case letters. I am not allowed to youse a HashMap.

This is my code till now: I'ts not working, I think I've got the wrong strategy here. Can you help me please?

```
public class Stringray extends MiniJava{
public static void main(String[] args) {
    // Texteingabe
    String input = readString("Geben Sie einen Text ein: ");

    String output = "";
    int i = 0;

    // Häufigkeit der Buchstaben
    int count = 0;
    char letter = 'a';
    while(i < input.length()) {
            while(i < input.length()) {
                if(input.charAt(i) == letter) {
                    while(i < input.length()) {
                        count++;
                        i++;
                    }
                    output = output + letter + ": " + count + "\t";
                }
                i++;
            }
            letter++;
    }
    write(output);
}
}

```

Answer: 
A really preformant way to do this in linear time is using a HashMap

```
public class Stringray extends MiniJava {

    public static void main(String[] args) {
        String input = "Geben Sie einen Text ein: ";
        System.out.println(countLetters(input));
    }

    public static HashMap<Character, Integer> countLetters(String input) {
        HashMap<Character, Integer> hashMap = new HashMap<>();
        final int length = input.length();
        for (int i = 0; i < length; i++) {
            Character currentChar = Character.toLowerCase(input.charAt(i));
            if (Character.isAlphabetic(currentChar)) {
                if (hashMap.containsKey(currentChar)) {
                    hashMap.put(currentChar, hashMap.get(currentChar) + 1);
                } else {
                    hashMap.put(currentChar, 1);
                }
            }
        }
        return hashMap;
    }

}

```

You need to consider that Upper and Lower case are the same and discard non alphabetic characters. Once you have all the information in the hashmap, the way you show it console is another matter. If you need to show a zero for the letters that are not present in your text it would be better to initialize the hashmap to that.
The requirements need some analysis.

There is a non-functional requirement not to use a hash map. A hash map is just a way to reduce the storage needs for sparse data at the expense of a little time. It's easy to use but makes the code a bit more complicated in Java. So, the straightforward way is to use an array. Memory is cheap, hopefully.

The functional requirements are more problematic:

* *Letters:* Unicode is the character set used by Java and it does have designated letters [Character.isLetter](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isLetter-int-)
* *Alphabetical:* Language academies and popular convention determine which letters are in *The Alphabet* and the order of letters the language's various writing systems. As no language or script was mentioned, let's punt on this and use the character set's codepoint ordering (lexicographic) and report on every letter.
* *No need to distinguish between upper and lower case letters:* Because letter casing is culture/locale-specific, it really would be more straightforward to look at each letter on its own and not try to define sets of upper and lower case letters. (There are more cases anyway.) It seems stated as an option so let's skip it for now.

.

```
int[] codepointCounts = new int[Character.MAX_CODE_POINT + 1]; // min to max, inclusive

String input = "Häufigkeit der Buchstaben";

for(int c : input.codePoints().toArray()){ 
    codepointCounts[c]++;       
}
for (int c = Character.MIN_CODE_POINT; c <= Character.MAX_CODE_POINT; c++) {
    if (codepointCounts[c] > 0) { 
        if (Character.isLetter(c)) {
            write(
                new String(Character.toChars(c)) + '\t' + 
                codepointCounts[c] + '\t' + 
                Character.getName(c));
        }
    }
}

```