Loading...
htopalov avatar htopalov 2 Точки

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 30 Точки

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

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

https://pastebin.com/uZjPh6g8

0
Elena123456 avatar Elena123456 235 Точки

Здравейте,

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

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

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

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

 

1
MartinBG avatar MartinBG 4803 Точки

@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 235 Точки

@ MartinBG ,

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

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

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

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

Поздрави!

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