Професионална програма
Loading...
htopalov avatar htopalov 1 Точки

C# Fundamentals Associative Arrays-More exercise 01.Ranking 60/100

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

Условие: https://softuni.bg/downloads/svn/soft-tech/Sept-2019/CSharp/07.%20CSharp-Fundamentals-Associative-Arrays/07.%20CSharp-Fundamentals-Associative-Arrays-More-Exercise.docx

Моето решение: https://pastebin.com/7TNK3k3m

Тагове:
1
Fundamentals Module
daniel_dimitrov5 avatar daniel_dimitrov5 8 Точки

Здравей, нямам време да погледна обстойно. Мога само да ти дам готово решение :(

Дали е най-доброто? Едва ли, но все пак е нещо :)

https://pastebin.com/uZjPh6g8

0
Elena123456 avatar Elena123456 167 Точки

Здравейте,

същата задача я има и в Advanced модула - Sets and Dictionaries Advanced - Exercise.

Искам да помоля някой ако има възможност да погледне кода ми, който е 100/100- https://pastebin.com/assFnAH1 .

Имам съмнения, дали е оптимален вариант, защото досега съм попадала на подобни задачи с решения или само с класове, или само с речници, а моето решение е комбинация на клас с речник. Притесняваме това, че досега не съм виждала подобно използване на клас с речник. Моят вариант оптимален ли е или е по-добре само с класове, или само с речници? Като цяло достатъчно четим ли е кода?

Предварително благодаря! smiley

 

1
MartinBG avatar MartinBG 3610 Точки

@Elena123456

Кодът е напълно четим (нарочно минах направо през него без да чета условието), но - като всеки код, може да се подобри малко. :)

 

Избягвайте да използвате while(true) + break някъде в тялото на цикъла. Все едно да имате for цикъл с break по някакво условие в него, вместо да напишете това условие директно като проверка за терминиране на цикъла (втората част ог for-a).

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

 

Този код:

            while (true)
            {
                string input = Console.ReadLine();
                if (input == "end of contests")
                {
                    break;
                }
                ...
            }

Може да се разпише и така:

            string input;
            while ((input = Console.ReadLine()) !="end of contests")
            {
                // ...
            }

 

Избягвайте да използвате много нива на вложени if блокове - освен чисто визуалното изместване надясно (може да е проблем при по-тесен прозорец на IDE-то), затруднява и четенето, защото се налага да помним в коя точно логическа част се намираме в момента. Освен това, при вложени if-ове е по-вероятно да имаме повторяемост на код или на логика (на практика правим едно и също нещо, но при различни условия).

Цялата част от задачата, която чете резултатите на студентите може да се разпише и само с няколко независими if-a:

            while ((input = Console.ReadLine()) != "end of submissions")
            {
                string[] inputArray = input.Split("=>");
                string contest = inputArray[0];
                string password = inputArray[1];
                string studentName = inputArray[2];
                int points = int.Parse(inputArray[3]);

                if (!dictContestPassword.ContainsKey(contest) || dictContestPassword[contest] != password)
                {
                    continue;
                }

                if (!dictNameStudent.ContainsKey(studentName))
                {
                    dictNameStudent.Add(studentName, new Student(studentName));
                }

                Student student = dictNameStudent[studentName];

                if (!student.ContestsWithPoints.ContainsKey(contest))
                {
                    student.ContestsWithPoints.Add(contest, points);
                }

                if (student.ContestsWithPoints[contest] < points)
                {
                    student.ContestsWithPoints[contest] = points;
                }
            }

Забележете, че няма никаква логическа повторяемост и разклонения, операциите се извършват в желаната последователност и са максимално независими:

- ако състезанието или паролата са невалидни - спираме текущата итерация (continue)

- ако няма такъв студент - създаваме го

- ако студента не е участвал в състезанието - добавяме го

- ако текущият резултат е по-добър от предходния - ъпдейтваме го

 

Друга промяна, която направих е да използвам Dictionary<string, Student> вместо List<Student>, защото това улеснява намирането по име. При глям брой студенти това ще подобри времето за намиране на студент, но при малък брой студенти няма да има осезаема разлика в сравнение с List-a. При всички случаи, обаче, кодът е по-четим с Dictionary.

 

Това е цялото преработено решение.

2
Elena123456 avatar Elena123456 167 Точки

@ MartinBG ,

благодаря за подобряването на четимостта на кода ми.

За while(true) с breаk чак сега направих сравнението му с while ((input = Console.ReadLine()) != "end of contests") и найстина втория вариант е доста по-четим, защото веднага се вижда докога ще се изпълнява цикъла.

Разбрах какво имате предвид за if/else проверките- ако са прекалено много вложени проверки човек трябва да помни логиката от преди няколко реда, което нарушава четимостта. Но със сигурност ще ми трябва малко време за да свикна с четимостта без вложени if/else, защото на упражнения само по този начин са ни показвали.

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

Поздрави!

1