Search code examples
javaswingnumbersjlistalphabet

Converting letters to alphabet position with two JLists


I'm trying to replace all words (alphabet letters) from JList1 to the number corresponding its place in the alphabet to JList2 with the press of the Run button. (ex. A to 01) And if it's not an English alphabet letter then leaving it as it is. Capitalization doesn't matter (a and A is still 01) and spaces should be kept.

For visual purposes:

https://i.sstatic.net/PYhYA.png

"Apple!" should be converted to "0116161205!"
"stack Overflow" to "1920010311 1522051806121523"
"über" to "ü020518"

I have tried a few methods I found on here, but had zero clue how to add the extra 0 in front of the first 9 letters or keep the spaces. Any help is much appreciated.


Solution

  • So given...

    (ex. A to 01) And if it's not an English alphabet letter then leaving it as it is. Capitalization doesn't matter (a and A is still 01) and spaces should be kept.

    This raises some interesting points:

    • We don't care about non-english characters, so we can dispense with issues around UTF encoding
    • Capitalization doesn't matter
    • Spaces should be kept

    The reason these points are interesting to me is it means we're only interested in a small subset of characters (1-26). This immediately screams "ASCII" to me!

    This provides an immediate lookup table which doesn't require us to produce anything up front, it's immediately accessible.

    A quick look at any ascii table provides us with all the information we need. A-Z is in the range of 65-90 (since we don't care about case, we don't need to worry about the lower case range.

    But how does that help us!?

    Well, this now means the primary question becomes, "How do we convert a char to an int?", which is amazingly simple! A char can be both a "character" and a "number" at the same time, because of the ASCII encoding support!

    So if you were to print out (int)'A', it would print 65! And since all the characters are in order, we just need to subtract 64 from 65 to get 1!

    That's basically your entire problem solved right there!

    Oh, okay, you need to deal with the edge cases of characters not falling between A-Z, but that's just a simple if statement

    A solution based on the above "might" look something like...

    public static String convert(String text) {
        int offset = 64;
        StringBuilder sb = new StringBuilder(32);
        for (char c : text.toCharArray()) {
            char input = Character.toUpperCase(c);
            int value = ((int) input) - offset;
            if (value < 1 || value > 25) {
                sb.append(c);
            } else {
                sb.append(String.format("%02d", value));
            }
        }
        return sb.toString();
    }
    

    Now, there are a number of ways you might approach this, I've chosen a path based on my understanding of the problem and my experience.

    And based on your example input...

    String[] test = {"Apple!", "stack Overflow", "über"};
    for (String value : test) {
        System.out.println(value + " = " + convert(value));
    }
    

    would produce the following output...

    Apple! = 0116161205!
    stack Overflow = 1920010311 1522051806121523
    über = ü020518