Професионална програма
Loading...
+ Нов въпрос
Elena123456 avatar Elena123456 168 Точки

03. Plant Discovery -Programming Fundamentals Final Exam - 09 August 2020

Здравейте,

моля за помощ за следната задача- https://judge.softuni.bg/Contests/Practice/Index/2518#2

Разгледах доста други решения, но така и не успях да си намеря грешката. Може би направих вече около 10 опита в Judge, но моето решение е все още 50/100.

Последният тест ми показва, че аутпута ми е грешен, а  на тестове 2,4 и 5- Runtime error.

https://pastebin.com/J5N7KS2j

 

Това ми е сортировката и поне при мен показва правилно сортирането на двата речника:

 private static void PrintAndSortMetod(Dictionary<string, int> dictPlantRarity, Dictionary<string, List<double>> dictPlantRating)
        {
            Console.WriteLine("Plants for the exhibition: ");

            var newsortedDict = new Dictionary<string, List<double>>();
            foreach (var kvp in dictPlantRating.OrderByDescending(x => x.Value.Average()))
            {
                string plant = kvp.Key;
                double averageRating = kvp.Value.Average();
                int rarity = dictPlantRarity[plant];
                double rarityDouble = (double)rarity;

                newsortedDict[plant] = new List<double>();
                newsortedDict[plant].Add(rarityDouble);
                newsortedDict[plant].Add(averageRating);
            }

            foreach (var kvp in newsortedDict.OrderByDescending(x => x.Value[0]))
            {
                string plant = kvp.Key;
                double rarity = kvp.Value[0];
                double averageRating = kvp.Value[1];
                Console.WriteLine($"- {plant}; Rarity: {rarity}; Rating: {averageRating:F2}");
            }
        }
    }

 

Може би проблема ми е в Reset командата:

else if (leftPartOfCommand == "Reset")

{

if (dictPlantRating.ContainsKey(plant))

{

dictPlantRating[plant] = new List<double>();

dictPlantRating[plant].Add(0.00);

}

}

Тагове:
1
C# Fundamentals 04/12/2020 01:47:48
MartinBG avatar MartinBG 3511 Точки
Best Answer

Има 2 проблема в решението:

  1. Ред №69 е излишен и заради него има грешен резултат на последния тест (брои се като рейтинг и по този начин променя реалния рейтинг на растението):
    dictPlantRating[plant].Add(0.00);

     

  2. На редове №89 и №92 ще се хвърли System.InvalidOperationException: Sequence contains no elements за растения, които нямат рейтинг (т.е. листа с рейтингите е празен):

    foreach (var kvp in dictPlantRating.OrderByDescending(x => x.Value.Average()))
    {
        //...
        double averageRating = kvp.Value.Average();
        //...
    }
    

    Примерен фикс:
     

    foreach (var kvp in dictPlantRating.OrderByDescending(x => x.Value.Count > 0 ? x.Value.Average() : 0))
    {
        //...
        double averageRating = kvp.Value.Count > 0 ? kvp.Value.Average() : 0;
        //...
    }

     

Проверките на редове №49, №58 и №66 са излишни, защото валидността на растението вече е потвърдена на ред №40.

3
04/12/2020 03:59:46
Elena123456 avatar Elena123456 168 Точки

@ MartinBG,

много благодаря! :)

Само да се уверя, че съм разбрала и предварително се извинявам, ако понякога досаждам с повторенията си и обобщенията си. Но за жалост много пъти ми се е случвало след опит за обобщение да съм изпуснала или неразбрала нещо.

Значи с този синтаксис:

dictPlantRating[plant].Add(0.00);

без да искам увеличавам x.Value.Count() и при последващо изчисляване на Average() винаги Caunt() ще ми е с 1 повече и никога Average() няма да ми е правилен. Защото при изчисляването му първо програмата ще сумира всички стойности, след което ще ги раздели на  Count(), а при мен Count() винаги ще е грешен с този допълнителен ред, имайки допълнителна стойност 0,00.

 

А тук:

foreach (var kvp in dictPlantRating.OrderByDescending(x => x.Value.Count > 0 ? x.Value.Average() : 0))

{

    //...

    double averageRating = kvp.Value.Count > 0 ? kvp.Value.Average() : 0;

    //...

се застраховаме, че винаги при изчисляването на Average() (първо сумиране на елементите и последващо делене на Count()), че Count() няма да е 0 и програмата да се опита да дели на 0 и да хвърли Exception. За това само ако x.Value.Count>0, само тогава искаме да се изчислява Average(). В противен случай, ако Count() = 0, т.е нямаме никакъв Рейтинг, то цялото x.Value си остава със стойност 0 и без програмата да се опитва да изчислява Average().

А за double averageRating- само ако kvp.Value.Count>0 програмата да вземе Average(), но в противен случай double averageRating да се сетне на 0.

Ако това, което съм разбрала е така, то си отбелязвам, че винаги при изчисляване на Average() трябва да проверяваме дали знаменателя(Count()) не е 0, както досега за всичко сме проверявали дали не делим на 0.

Проверките също си ги оправих и ето редактирания ми код https://pastebin.com/mfXHyY4s , като много благодаря за корекциите и обясненията! :)

Поздрави!

 

 

1
MartinBG avatar MartinBG 3511 Точки

Elena123456

Да, правилно сте разбрала! yes

smiley

1
petrovmilen38 avatar petrovmilen38 0 Точки

@ MartinBG

https://pastebin.com/QXMQRETe

87/100 моля те  помогни ми да си намеря грешката.

Ти си Бога на този форум!!!!

0
11/12/2020 19:58:56
matthewgrace avatar matthewgrace -3 Точки

Да, това ще да е доста полезно... случи ми се 2 пъти до сега, хаха .. cookie clicker

-4