Я делаю следующую задачу кодирования в Java:

/**
     * 4. Given a word, compute the scrabble score for that word.
     * 
     * --Letter Values-- Letter Value A, E, I, O, U, L, N, R, S, T = 1; D, G = 2; B,
     * C, M, P = 3; F, H, V, W, Y = 4; K = 5; J, X = 8; Q, Z = 10; Examples
     * "cabbage" should be scored as worth 14 points:
     * 
     * 3 points for C, 1 point for A, twice 3 points for B, twice 2 points for G, 1
     * point for E And to total:
     * 
     * 3 + 2*1 + 2*3 + 2 + 1 = 3 + 2 + 6 + 3 = 5 + 9 = 14
     * 
     * @param string
     * @return
     */

Моя идея - вставить все эти буквы в хэш-карту, выполнив что-то вроде этого:

map.add({A,,E,I,O,U,L,N,R,S,T}, 1);

Есть ли способ сделать это в Java?

1
patzi 3 Мар 2018 в 19:39

4 ответа

Лучший ответ

Вы сказали в своих комментариях, что хотели бы иметь возможность добавлять все эти записи в одном утверждении. Хотя Java не является отличным языком для таких вещей в одном выражении, это можно сделать, если вы действительно намерены это сделать. Например:

Map<Character, Integer> scores =
    Stream.of("AEIOULNRST=1","DG=2","BCMP=3","FHVWY=4" /* etc */ )
        .flatMap(line -> line.split("=")[0].chars().mapToObj(c -> new Pair<>((char)c, Integer.parseInt(line.split("=")[1]))))
        .collect(Collectors.toMap(Pair::getKey, Pair::getValue));

System.out.println("C = " + scores.get('C'));

< Сильный > Вывод :

C = 3

В приведенном выше коде я сначала строю поток всех записей (в виде пар) и собираю их в карту.

< EM > Примечание :

Класс Pair, который я использовал выше, из javafx.util.Pair. Однако вы также можете легко использовать AbstractMap.SimpleEntry, свой собственный класс Pair или любой тип данных коллекции, способный содержать два объекта.


Лучший подход

Другая идея - написать свой собственный вспомогательный метод. Этот метод может быть помещен в класс, который содержит аналогичные вспомогательные методы. Такой подход был бы более идиоматичным, более легким для чтения и, следовательно, более легким в обслуживании.

public enum MapHelper {
; // Utility class for working with maps
public static <K,V> void multiKeyPut(Map<? super K,? super V> map, K[] keys, V value) {
for(K key : keys) {
    map.put(key, value);
}}}

Тогда вы бы использовали это так:

Map<Character, Integer> scores = new HashMap<>();
MapHelper.multiKeyPut(scores, new Character[]{'A','E','I','O','U','L','N','R','S','T'}, 1);
MapHelper.multiKeyPut(scores, new Character[]{'D','G'}, 2);
MapHelper.multiKeyPut(scores, new Character[]{'B','C','M','P'}, 3);
/* etc */
4
Patrick Parker 24 Окт 2019 в 15:41

Возьмите массив длиной 26, каждый элемент представляет счет алфавита. Итак, у нас будет такой массив:

alphabetScore = [1,3,3,2,.....................];

Теперь, переберите слово и продолжайте добавлять счет текущего алфавита в общий счет.

1
ncoder 3 Мар 2018 в 16:45

Я думаю, что не стоит хранить список дополнительных символов в качестве ключей (посмотрите этот вопрос) и одно значение, соответствующее этому ключу, но если вам это действительно нужно , вы можете попробовать это:

Map<ArrayList<Character>, Integer> map = new HashMap<>();
map.put(new ArrayList<Character>(Arrays.asList('A', 'E',...)), 1);
map.put(new ArrayList<Character>(Arrays.asList('D', 'G',...)), 2);

Лично , я бы предложил использовать HashMap<Integer, ArrayList<Character>> - ключи являются "значениями" набора букв (например, ключ будет равен 1 для ArrayList связывающих букв: A, E и т. д. ), в качестве значения, соответствующего этому ключу Integer, можно ArrayList хранить символы (A, E, ...). Вы можете достичь этого результата с:

Map<Integer, ArrayList<Character>> map = new HashMap<>();
map.put(1, new ArrayList<Character>(Arrays.asList('A', 'E',...)));
map.put(2, new ArrayList<Character>(Arrays.asList('D', 'G',...)));
1
Przemysław Moskal 3 Мар 2018 в 19:02

Map не имеет методов, которые работают с несколькими ключами, но вы можете передать список этих символов и вызвать forEach:

Map<Character, Integer> scores = new HashMap<>();
Stream.of('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T')
      .forEach(c -> scores.put(c, 1));
Stream.of('D', 'G').forEach(c -> scores.put(c, 2));
// etc...
0
Mureinik 3 Мар 2018 в 16:49