92 lines
3.1 KiB
C
92 lines
3.1 KiB
C
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "numbers.h"
|
|
|
|
/**
|
|
* @brief Selbsttest für createNumbers() und getDuplicate().
|
|
*
|
|
* Erzeugt ein Array aus len Zufallszahlen mit genau einem duplizierten Wert,
|
|
* validiert die Eigenschaften per Zähl-Array (Wertebereich, Häufigkeiten)
|
|
* und prüft anschließend, ob getDuplicate() dasselbe Duplikat ermittelt.
|
|
*
|
|
* Rückgabecodes:
|
|
* 0: OK
|
|
* 1: createNumbers() fehlgeschlagen
|
|
* 2: Speicherfehler für counts
|
|
* 3: Wert außerhalb des Bereichs [1..2*len]
|
|
* 4: Ein Wert erscheint öfter als zweimal
|
|
* 5: Nicht genau ein Duplikat gefunden
|
|
* 6: getDuplicate() liefert anderes Ergebnis als Zählung
|
|
*/
|
|
int main(void)
|
|
{
|
|
unsigned int len = 100; // Anzahl zu erzeugender Zahlen
|
|
unsigned int *nums = createNumbers(len);
|
|
if (nums == NULL) {
|
|
fprintf(stderr, "createNumbers returned NULL\n");
|
|
return 1; // Erzeugung fehlgeschlagen
|
|
}
|
|
|
|
unsigned int maxVal = 2 * len; // Erlaubter Bereich: [1 .. 2*len]
|
|
|
|
// Zähl-Array für Häufigkeiten pro Wert (Index 0 bleibt ungenutzt)
|
|
unsigned int *counts = calloc(maxVal + 1, sizeof(unsigned int));
|
|
if (counts == NULL) {
|
|
free(nums);
|
|
return 2; // Speicherfehler bei counts
|
|
}
|
|
|
|
// Häufigkeiten bestimmen und gleichzeitig Bereich prüfen
|
|
for (unsigned int i = 0; i < len; i++) {
|
|
unsigned int v = nums[i];
|
|
if (v == 0 || v > maxVal) { // sollte nicht passieren, wenn createNumbers korrekt ist
|
|
fprintf(stderr, "value out of expected range\n");
|
|
free(nums);
|
|
free(counts);
|
|
return 3;
|
|
}
|
|
counts[v]++; // Auftreten des Werts v zählen
|
|
}
|
|
|
|
// Exakt ein Wert muss doppelt vorkommen; keiner darf >2-mal vorkommen
|
|
int duplicatesFound = 0;
|
|
unsigned int duplicateValue = 0;
|
|
|
|
for (unsigned int v = 1; v <= maxVal; v++) {
|
|
if (counts[v] == 2) {
|
|
duplicatesFound++;
|
|
duplicateValue = v; // den doppelten Wert merken
|
|
} else if (counts[v] > 2) {
|
|
fprintf(stderr, "value %u appears more than twice\n", v);
|
|
free(nums);
|
|
free(counts);
|
|
return 4; // Vertragsbruch: zu häufiges Auftreten
|
|
}
|
|
// counts[v] == 0 oder 1 sind unkritisch
|
|
}
|
|
|
|
if (duplicatesFound != 1) {
|
|
fprintf(stderr, "expected exactly one duplicated value, found %d\n", duplicatesFound);
|
|
free(nums);
|
|
free(counts);
|
|
return 5; // zu wenige/zu viele Duplikate
|
|
}
|
|
|
|
// Ergebnis von getDuplicate() mit der Zählung abgleichen
|
|
unsigned int found = getDuplicate(nums, len);
|
|
if (found != duplicateValue) {
|
|
fprintf(stderr, "getDuplicate returned %u expected %u\n", found, duplicateValue);
|
|
free(nums);
|
|
free(counts);
|
|
return 6; // Abweichung zwischen Methoden
|
|
}
|
|
|
|
// Ressourcen freigeben und Erfolg melden
|
|
free(nums);
|
|
free(counts);
|
|
printf("test_numbers: OK (duplicate = %u)\n", duplicateValue);
|
|
return 0;
|
|
}
|