5
\$\begingroup\$

I've made code that scores each letter in a word you input according to the table below:

1: AEILNORSTU
2: DG
3: BCMP
4: FHVWY
5: K
8: JX
10: QZ

I appreciate any feedback, but the main reason of this post concerns the charPoint method. Should I rewrite this using switch? Or is there an even better way to write it?

package exercicios;

import com.sun.org.apache.xalan.internal.xsltc.compiler.Pattern;

import acm.program.*;

public class Ex5 extends ConsoleProgram{

    public void run(){
        String word = readLine("Enter a word: ");
        println(wordScore(word));

    }

    private int wordScore(String word){
        int score = 0;

        for (int i = 0; i < word.length(); i++){
            score += charPoint(word.substring(i, i+1));
        }


        return score;
    }
    private int charPoint(String ch){

        if (ch.matches("[AEILNORSTU]")){
            return 1;
        } else if (ch.matches("[DG]")){
            return 2;
        } else if (ch.matches("[BCMP]")){
            return 3;
        } else if (ch.matches("[FHVWY]")){
            return 4;
        } else if (ch.matches("[K]")){
            return 5;
        } else if (ch.matches("[JX]")){
            return 8;
        } else if (ch.matches("[QZ]")){
            return 10;
        } else return 0;

    }
}
\$\endgroup\$
2
  • \$\begingroup\$ Is there some reasoning behind the points? You could try to discover any connection between ASCII code and the letter "value" and avoid the if..else or switch at all. \$\endgroup\$
    – fracz
    Commented Dec 27, 2016 at 18:24
  • 1
    \$\begingroup\$ @fracz I think it's the score given in Scrabble for each letter in the word you make \$\endgroup\$
    – Guilherme
    Commented Dec 27, 2016 at 19:48

1 Answer 1

1
\$\begingroup\$

It may be simpler (and definietly faster when it comes to larger data) to create a private static final Map<Character, Integer> with LETTER -> VALUE mapping prior to any calculations. Besides repeating the put many times when constructing it, you can be even cooler although less readable IMO:

private static final Map<Character, Integer> LETTER_TO_POINT;

static {
    final Map<Character, Integer> letterToPoint = new HashMap<>();
    // letterToPoint.put('A', 1);
    // letterToPoint.put('B', 3);
    // booooooring :-(

    BiConsumer<String, Integer> rememberPointValues = (letters, points) -> {
        for (char letter : letters.toCharArray()) {
            letterToPoint.put(letter, points);
        }
    };
    rememberPointValues.accept("AEILNORSTU", 1);
    rememberPointValues.accept("DG", 2);
    rememberPointValues.accept("BCMP", 3);
    rememberPointValues.accept("FHVWY", 4);
    rememberPointValues.accept("K", 5);
    rememberPointValues.accept("JX", 8);
    rememberPointValues.accept("QZ", 10);
    LETTER_TO_POINT = Collections.unmodifiableMap(letterToPoint);
}

Once you have that, the charPoint method is much simpler:

private int charPoint(char ch) {
  return LETTER_TO_POINT.get(ch);
}

Moreover, you can iterate over the letters in the string like that:

for (char letter : word.toCharArray()) {
  score += charPoint(letter);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.