Поиск ученика
Лиза пришла возмущаться: учитель неправильно сложил её баллы. У неё должно быть 35, а не 27. Программе нужна функция, которая исправляет результат ученика по имени. Но сначала ей нужно найти ученика в names, то есть найти его индекс.
Поиск — это приём из урока о циклах: цикл проходит по элементам, а когда находит нужный, запоминает его индекс, и break завершает цикл, потому что искать дальше незачем. Переменная для индекса начинается с -1. Такого индекса нет ни в одном векторе. Если цикл ничего не найдёт, переменная останется равной -1, а это значит, что искомого в векторе нет:
#include <iostream>
#include <string>
#include <vector>
int findSubject(const std::vector<std::string>& subjects, std::string wanted) {
int index = -1;
for (int i = 0; i < subjects.size(); i++) {
if (subjects[i] == wanted) {
index = i;
break;
}
}
return index;
}
int main() {
std::vector<std::string> timetable = {"Математика", "Физика", "История"};
std::cout << findSubject(timetable, "Физика") << std::endl;
std::cout << findSubject(timetable, "Химия") << std::endl;
return 0;
}1
-1Строки сравниваются через ==, и сравнение точное: "лиза" — это не то же самое, что "Лиза".
Функция fixScore() получает оба вектора. names она только читает, поэтому получает его как константную ссылку. scores она меняет, поэтому получает его как ссылку без const.
Порядок вызовов в main() важен. Лиза набрала на тесте 35 баллов, и 3 балла за неудачный вопрос она получает, как и все. Поэтому исправление идёт до вызова addPoints(scores, 3). После него исправление перезаписало бы бонус Лизы, и у неё было бы всего 35 баллов.
А что, если учитель введёт имя, которого нет в векторе? Макс, например, учится в параллельном классе. findStudent() вернёт -1, а scores[-1] — за пределами вектора. Из урока о векторах вы знаете, что индекс вне диапазона — это баг: программа может аварийно завершиться или молча перезаписать память, которая вектору не принадлежит. Поэтому fixScore() сначала проверяет индекс.
Задание
- 1
Под
addPoints()напишите функциюint findStudent(const std::vector<std::string>& names, std::string name), которая возвращает индекс ученика с именемnameили-1, если его нет в векторе. Когда ученик найден, завершите цикл черезbreak. - 2
Под ней напишите функцию
void fixScore(const std::vector<std::string>& names, std::vector<int>& scores, std::string name, int newScore), которая находит индекс ученика черезfindStudent()и задаёт ему результатnewScore. - 3
В
main()над вызовомaddPoints()исправьте результат Лизы:fixScore(names, scores, "Лиза", 35);. Теперь у Лизы 35 + 3 = 38 баллов, и результаты заканчиваются так:Лиза, баллы: 38, оценка B Средний балл: 38.2 Лучший: Тимур (баллы: 50)Если у Лизы 35 баллов, значит, вы вызываете исправление после
addPoints(). - 4
Добавьте в
fixScore()проверку: еслиfindStudent()возвращает-1, выведитеМакс не учится в этом классе., но вместоМаксподставьте имя, которое получила функция, и не меняйте результаты. Затем проверьте её: под исправлением для Лизы добавьтеfixScore(names, scores, "Макс", 40);. Над результатами появится:Макс не учится в этом классе.