Loading...
SimeonKazandzhiev avatar SimeonKazandzhiev 3 Точки

Plant Discovery от Final Exam

Моля за малко помощ, докарвам логиката но в принтирането се спъвам .

Ако някой има решение на 100/100 моля да сподели .

Ето го и кода ми:

https://pastebin.com/iQqrBpRv

Благодаря предварително

Тагове:
0
Programming Fundamentals
MartinBG avatar MartinBG 4803 Точки

Имаше няколко пропуска по условието, като например да се извежда "error" при невалидна команда, както и да се презаписва rarity, ако растението бъде въведено повече от веднъж в началото.

 

Тази задача би се решила доста по-лесно и прегледно с помощен клас, но ето и оправеното решение с два Map-а :

 

import java.util.*;

public class PlantDiscovery {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        Map<String, Integer> plants = new HashMap<>();
        Map<String, List<Double>> rating = new HashMap<>();

        int n = Integer.parseInt(scanner.nextLine());

        for (int i = 0; i < n; i++) {
            String[] input = scanner.nextLine().split("<->");
            String plant = input[0];
            int rarity = Integer.parseInt(input[1]);
            plants.compute(plant, (k, v) -> rarity);
            rating.putIfAbsent(plant, new ArrayList<>());
        }

        String input;
        while (!"Exhibition".equals(input = scanner.nextLine())) {
            String[] tokens = input.split(": ");
            String command = tokens[0];
            String[] elements = tokens[1].split(" - ");
            String name = elements[0];

            if (!plants.containsKey(name)) {
                System.out.println("error");
                continue;
            }

            switch (command) {
            case "Rate":
                double rate = Double.parseDouble(elements[1]);
                rating.get(name).add(rate);
                break;
            case "Update":
                int rarity = Integer.parseInt(elements[1]);
                plants.compute(name, (k, v) -> rarity);
                break;
            case "Reset":
                rating.get(name).clear();
                break;
            default:
                System.out.println("error");
            }
        }

        System.out.println("Plants for the exhibition:");
        plants.entrySet()
                .stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue()
                        .thenComparingDouble(x -> rating.get(x.getKey()).stream()
                                .mapToDouble(Double::doubleValue)
                                .average().orElse(0.0))
                        .reversed())
                .forEach(e -> System.out.printf("- %s; Rarity: %d; Rating: %.2f%n", e.getKey(), e.getValue(),
                        rating.get(e.getKey()).stream().mapToDouble(Double::doubleValue).average().orElse(0.0)));
    }
}

 

0
SimeonKazandzhiev avatar SimeonKazandzhiev 3 Точки

Благодаря ти много , да знаех че нямах случая за "error", но ме чупеше принтирането и сортирането едновременно на двата мапа,понеже никъде не го бяха показвали и не успях да намеря инфо в интернет.Интересно,досега не бях използвал "compute".Би ли ми обяснил накратко в кои случаи е удобно да се използва.:)

1
MartinBG avatar MartinBG 4803 Точки

@SimeonKazandzhiev

 

Извинявам се за закъснелия отговор.

 

Map#compute(K, BiFunction(K, V)) ни дава възможност едновременно да достъпим и да променим стойността на вече съществуващ ключ. Това е полезно, например, ако искаме да конкатенираме стрингове, както е показано и в документацията:

Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). For example, to either create or append a String msg to a value mapping:

 
 map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))

 

Друго приложение е, ако искаме да сумираме старата стойност с нова. Например, ако в конкретната задача се искаше при повторно въвеждане на растение новото rarity да се добави към вече съществуващото:

plants.compute(plant, (k, v) -> Objects.requireNonNullElse(v, 0) + rarity);

Забележете, че задължително трябва да се прави проверка за null на старата стойност, преди тя да бъде използвана (ще е null ако растението се въвежда за първи път или ако по някаква причина е имало стойност null). Може да се използва тернарен оператор (примера от официалната документация) или Objects#requireNonNullElse​(T obj, T defaultObj) - и двете правят едно и също в случая.

 

След като изяснихме това, вече сигурно се досещате, че използването на compute в конкретната задача е абсолютно ненужно (и нежелателно) и може да се заменени с Map#put​(K key, V value), което ни дава желаната функционалност, без да събужда въпроси какво прави и защо е използвано (т.е. допринася за четимостта на кода) blush

plants.put(plant, rarity);

 

1
18/11/2020 10:30:02
Georgieva_Nadezhda avatar Georgieva_Nadezhda 28 Точки

Здравей MartinBG,

Можеш ли да напишеш на части разбито по-подробно какво се први в тази част на сортирането без да се ползват готовите методи Map.Entry.<String, Integer>comparingByValue() .thenComparingDouble. Благодаря ти. Разбирам какво е сортирането спрямо уловието, но синтаксиса ми е доста сложен към момента и ако знаеш нещо по-лесно, много ще ми помогнеш :) 

.sorted(Map.Entry.<String, Integer>comparingByValue() .thenComparingDouble(x -> rating.get(x.getKey()).stream() .mapToDouble(Double::doubleValue) .average().orElse(0.0)) .reversed())

1
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.