Tracks
/
C++
C++
/
Übungen
/
Notenvergabe
Notenvergabe

Notenvergabe

Lernübung

Einführung

Arrays und Vektoren

C++ bietet verschiedene Container, um Elemente desselben Typs geordnet zu speichern. Es gibt std::array für Container mit fester Größe und std::vector, der dynamisches Vergrößern und Verkleinern mitbringt.

Konstruktion

Wenn du ein Array oder einen Vektor deklarierst, musst du den Typ der Elemente angeben, die der Container aufnehmen soll. Arrays brauchen außerdem eine Größe. Schau dir diese Beispiele an, um die Initialisierung der beiden Containertypen zu sehen:

#include <array>
#include <string>

// std::array<element_type, size> variable_name {list of elements}
std::array<std::string, 3> indie_rock {"yeah", "yeah", "yeah"};
// indie_rock contains the elements "yeah" three times

Vektoren brauchen meist mehr Platz, da sie Speicher für weiteres Wachstum reservieren. Eine Größe musst du nicht angeben:

#include <vector>

// std::vector<element_type> variable_name {list of elements}
std::vector<int> countdown {3, 2, 1};
// countdown contains the elements 3, 2 and 1

Hinweis: Die genauen Mechanismen hinter dem Template-Konzept musst du noch nicht kennen, es bekommt weiter unten im Lehrplanbaum ein eigenes Konzept.

Elementzugriff

Vektoren und Arrays teilen sich dieselben Funktionen, um auf ihre Elemente zuzugreifen. Mit den Memberfunktionen front und back bekommst du das erste und das letzte Element des Containers. Außerdem gibt es at und den []-Operator, um auf bestimmte Elemente zuzugreifen.

countdown[0];
// => 3
countdown.at(2);
// => 1
countdown[1] = 4;
// countdown now contains 3, 4 and 1
indie_rock.back() = "yeahs";
// indie_rock is now "yeah", "yeah", "yeahs"

Hinweis: Wenn du eine Position wählst, die nicht im Bereich deines Containers liegt, kann [] zu undefiniertem Verhalten führen. Die Funktion at würde eine Exception auslösen, was dir auf lange Sicht das Leben erleichtern könnte.

Vektormodifikatoren

Da ein vector in seiner Größe nicht festgelegt ist, lassen sich Elemente hinzufügen oder entfernen. Zwei häufig verwendete Funktionen dafür sind emplace_back und pop_back.

std::vector<std::string> witches {"Holly", "Alyssa", "Shannen"};
witches.pop_back();
// Shannen is no longer with the witches
witches.emplace_back("Rose");
// Rose has joined the team

Kapazität

Mit der Memberfunktion empty kannst du prüfen, ob ein Container leer ist. Wenn du die Anzahl der Elemente wissen willst, kannst du size verwenden.

Anleitung

Du bist Tutor und korrigierst die Prüfungen der Schüler. Die Ergebnisse per Hand zu verwalten wird mit der Zeit mühsam und fehleranfällig. Du beschließt, die Sache etwas interessanter zu machen, und stellst ein paar Funktionen zusammen, mit denen du die Ergebnisse der Klasse zählst und berechnest.

1. Punktzahlen abrunden

Bei einzelnen Prüfungsfragen kannst du zwar „Teilpunkte“ vergeben, aber die Gesamtpunktzahl einer Prüfung muss ein int sein. Bevor du also mit den Punktzahlen der Klasse irgendetwas anderes machen kannst, musst du die Ergebnisse durchgehen und alle double-Punktzahlen in ints umwandeln.

Schreibe die Funktion round_down_scores(), die einen vector von student_scores entgegennimmt. Die von den Schulen gewünschte Rundung ist ein Abschneiden. Zum Glück kann C++ mit static_cast einen Typ in einen anderen umwandeln. Die Umwandlung mit static_cast von double nach int schneidet alle Nachkommastellen ab. Diese Funktion soll den eingegebenen vector entgegennehmen und mit return einen neuen Vektor zurückgeben, in dem alle Punktzahlen in ints umgewandelt sind.

std::vector<double> student_scores {90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3};
round_down_scores(student_scores)
// => {90, 40, 55, 70, 30, 25, 80, 95, 38, 40}

Es gibt noch andere Methoden, die dasselbe Ergebnis liefern, aber einen Cast sieht man häufig.

int new_PI{static_cast<int>(3.14) + static_cast<int>(0.001592653589)};
// new_PI is 3.

2. Schüler ohne Bestehensnote

Beim Korrigieren der Prüfung ist dir aufgefallen, dass einige Schüler nicht so gut abgeschnitten haben, wie du gehofft hattest. Aber du warst abgelenkt und hast vergessen, dir genau zu notieren, wie viele Schüler es waren.

Schreibe die Funktion count_failed_students(), die einen vector von student_scores entgegennimmt. Diese Funktion soll zählen, wie viele Schüler keine Bestehensnote haben, und diese Anzahl als Ganzzahl zurückgeben. Um die Prüfung zu bestehen, braucht ein Schüler eine Punktzahl von mehr als 40.

count_failed_students({90,40,55,70,30,25,80,95,38,40});
// => 5

3. Buchstabennoten berechnen

Die Lehrkraft, der du hilfst, vergibt neben den Punktzahlen auch gern Buchstabennoten. Da Schüler in einer Prüfung selten eine Punktzahl von 100 erreichen, werden die unteren Schwellenwerte der „Buchstabennoten“ anhand der höchsten erreichten Punktzahl berechnet und gleichmäßig zwischen der höchsten Punktzahl und der Durchfallgrenze von <= 40 verteilt.

Schreibe die Funktion letter_grades(), die die „höchste“ Punktzahl der Prüfung als Parameter entgegennimmt und ein array (kein Vektor) mit den unteren Schwellenwerten für jedes Notenintervall im „amerikanischen Stil“ zurückgibt: ["D", "C", "B", "A"].

/*Where the highest score is 100, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 55
 56 <= "C" <= 70
 71 <= "B" <= 85
 86 <= "A" <= 100
*/

letter_grades(100);
// => {41, 56, 71, 86}


/*Where the highest score is 88, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 52
 53 <= "C" <= 64
 65 <= "B" <= 76
 77 <= "A" <= 88
*/

letter_grades(88);
// => {41, 53, 65, 77}

4. Namen und Punktzahlen zuordnen

Du hast die Punktzahlen der Prüfung in absteigender Reihenfolge und die zugehörigen Schülernamen (in der Reihenfolge ihrer Prüfungsergebnisse sortiert). Du möchtest jedem Schülernamen seine Punktzahl zuordnen und eine Gesamtrangliste der Klasse ausgeben.

Schreibe die Funktion student_ranking() mit den Parametern student_scores und student_names. Ordne jedem Schülernamen im vector student_names die Punktzahl aus dem vector student_scores zu. Du kannst davon ausgehen, dass jeder übergebene vector von der höchsten zur niedrigsten Punktzahl sortiert ist. Die Funktion soll einen vector mit Strings im Format <rank>. <student name>: <student score> zurückgeben.

std::vector<int> student_scores {100, 99, 90, 84, 66, 53, 47};
std::vector<std::string> student_names {"Joci", "Sara","Kora","Jan","Indra","Bern", "Fred"};
student_ranking(student_scores, student_names)
// =>
//  {"1. Joci: 100", "2. Sara: 99", "3. Kora: 90", "4. Jan: 84", "5. Indra: 66", "6. Bern: 53", "7. Fred: 47"}

5. Eine „perfekte“ Punktzahl

Auch wenn eine „perfekte“ Punktzahl von 100 in einer Prüfung selten ist, ist es interessant zu wissen, ob mindestens ein Schüler sie erreicht hat.

Schreibe die Funktion perfect_score() mit den Parametern student_scores und student_names. Die Listen sind dieselben wie in Aufgabe 4. Die Funktion soll den <name> (als String) des ersten Schülers mit return zurückgeben, der in der Prüfung eine Punktzahl von 100 erreicht hat.

Wenn keine Punktzahl von 100 gefunden wird, soll ein leerer String "" zurückgegeben werden.

perfect_score({"Nur", "Tony", "Fatima"}, {90, 80, 100});
// => "Fatima"

perfect_score({"Nur", "Tony"}, {90, 80});
// => ""
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
C++ Exercism

Bereit, mit Notenvergabe zu starten?

Melde dich bei Exercism an, um C++ mit 19 Konzepte100 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.