Для участия в розыгрыше призов каждый дает его/ее имя.
Каждая буква имени имеет значение, которое соответствует ее рангу в
английском алфавите. A и a имеют ранг 1, B и b ранг 2 и так далее.
Длина имени добавляется к сумме этих рангов, следовательно, a
число сомов.
Массив случайных весов связан с именами, и каждый сом
умножается на соответствующий вес, чтобы получить то, что они называют выигрышем
номер.
Пример:
имена: «COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH " веса: [1, 4, 4, 5,
2, 1]
PauL -> сом = длина имени + 16 + 1 + 21 + 12 = 4 + 50 -> 54
вес, связанный с Павлом, равен 2, поэтому выигрышный номер Павла равен
54 * 2 = 108.
Теперь можно сортировать имена в порядке убывания выигрышных
номеров. Если у двух человек одинаковый выигрышный номер, отсортируйте их
в алфавитном порядке по именам. Задача:
parameters: st a string of firstnames, we an array of weights, n a rank
return: the firstname of the participant whose rank is n (ranks are numbered from 1)
Пример:
имена: «COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH» веса: [ 1, 4, 4, 5,
2, 1] n: 4
Функция должна вернуть: «PauL»
Примечание:
If st is empty return "No participants".
If n is greater than the number of participants then return "Not enough participants".
Я думал, что псевдокод выглядит так:
if names are empty return No participants
if n is greater than names length return Not enough participants
for each name
sum its length
for each character
sum its value in the alphabet
multiply sum by weight
store name and sum in the map
sort map descending by value
sort map alphabetically by key (if values are equal)
return key n from the map
Кроме того, я закодировал следующее:
import java.util.*;
import java.util.stream.*;
class Rank {
public static String nthRank(String st, Integer[] we, int n) {
System.out.println("\n\n\nNames: "+st+" weights: "+Arrays.toString(we)+" n: "+n);
if(st.isEmpty()) return "No participants";
String[] names = st.split(",");
if(n > names.length) return "Not enough participants";
String alphabet = "abcdefghijklmnopqrstuvwxyz";
int sum = 0;
Map map = new HashMap();
for(int i = 0; i < names.length; i++){
String currentName = names;
sum += currentName.length();
for(int j = 0; j < currentName.length(); j++){
char currentChar = Character.toLowerCase(currentName.charAt(j));
sum += alphabet.indexOf(currentChar) + 1;
}
map.put(currentName, sum*we);
System.out.println("Map: "+map.toString());
sum = 0;
}
map = map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
System.out.println("\n\nSorted Map: "+map.toString());
Object[] namesByWinningNumber = map.keySet().toArray();
Arrays.sort(namesByWinningNumber);
System.out.println("\n\n\nSorted names array: "+ Arrays.toString(namesByWinningNumber));
return map.keySet().toArray()[n-1].toString();
}
}
Когда ввод:
Names: William,Willaim,Olivia,Olivai,Lily,Lyli weights: [1, 1, 1, 1, 1, 1] n: 1
Ожидается:
Willaim
Но код выводит:
William
След:
Names: William,Willaim,Olivia,Olivai,Lily,Lyli weights: [1, 1, 1, 1, 1, 1] n: 1
Map: {William=86}
Map: {William=86, Willaim=86}
Map: {Olivia=74, William=86, Willaim=86}
Map: {Olivia=74, Olivai=74, William=86, Willaim=86}
Map: {Olivia=74, Olivai=74, William=86, Willaim=86, Lily=62}
Map: {Olivia=74, Olivai=74, William=86, Willaim=86, Lily=62, Lyli=62}
Sorted Map: {William=86, Willaim=86, Olivia=74, Olivai=74, Lily=62, Lyli=62}
Sorted names array: [Lily, Lyli, Olivai, Olivia, Willaim, William]
Итак, как мы видим, сначала я сортирую карту по значениям в порядке убывания. Затем я подумал, что если я получу ключи и отсортирую их в алфавитном порядке, то будут обработаны только те, у которых точно такие же значения; однако он сортирует все.
Как мы можем сортировать карту по убыванию значений, а затем в алфавитном порядке по ключам‽‽‽
Я также прочитал:
- Сортировка карты по значениям
- Какой самый простой способ распечатать массив Java?
- Сортировка массива в Java
- Почему в java.util.Set нет get(int index)?
- Хорошая печать коллекций Java (toString не возвращает красивый вывод)
- Метод извлечения всех ключей из LinkedHashMap в список
- Метод извлечения всех ключей из LinkedHashMap в список
- Метод извлечения всех ключей из LinkedHashMap в список
- Метод извлечения всех ключей из LinkedHashMap в список
- li>
Как получить значение из LinkedHashMap на основе индекса, а не ключа? - Сортировать карту по значениям
- Как эффективно перебирать каждую запись на карте Java?
РЕДАКТИРОВАТЬ:
Я читал: как написать Java 8 Comparator для значений Map внутри Map.Entry
Я также пытался написать свой собственный компаратор:
Comparator outerComparator = (pair1, pair2) -> {
if ((int)pair1.getValue() > (int)pair2.getValue()){
return 1;
}else if ((int)pair1.getValue() < (int)pair2.getValue()){
return -1;
}else{
return pair1.getKey().toString().compareTo(pair2.getKey().toString());
}
};
И используйте его следующим образом:
map = map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(outerComparator))
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
Однако наша консоль говорит:
./src/main/java/Rank.java:40: error: incompatible types: inference variable V has incompatible bounds
.sorted(Map.Entry.comparingByValue(outerComparator))
^
equality constraints: Integer
lower bounds: Entry,Object
where V,K are type-variables:
V extends Object declared in method comparingByValue(Comparator
Подробнее здесь: https://stackoverflow.com/questions/590 ... ly-by-keys