135 lines
3.9 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "numbers.h"
#include "bintree.h"
// Vergleichsfunktion für unsigned int (für Binärbaum und qsort)
static int compareUnsignedInt(const void *a, const void *b)
{
unsigned int valA = *(unsigned int *)a;
unsigned int valB = *(unsigned int *)b;
if (valA < valB) return -1;
if (valA > valB) return 1;
return 0;
}
// TODO: getDuplicate und createNumbers implementieren
/* * * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen.
* Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
* Duplizieren eines zufälligen Eintrags im Array.
* in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */
// Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries.
// Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while
// creating random numbers.
// Erzeugt ein Array mit len eindeutigen Zufallszahlen zwischen 1 und 2*len
// Verwendet Binärbaum zur Duplikatsvermeidung
// Gibt dann eine zufällige Zahl doppelt zurück
unsigned int *createNumbers(unsigned int len)
{
// Eingabevalidierung
if (len == 0)
{
return NULL;
}
// Array allokieren
unsigned int *numbers = (unsigned int *)malloc(len * sizeof(unsigned int));
if (numbers == NULL)
{
return NULL;
}
// Binärbaum zur Duplikatsprüfung erstellen
TreeNode *tree = NULL;
// Zufallsgenerator initialisieren
static int seedInitialized = 0;
if (!seedInitialized)
{
srand(time(NULL));
seedInitialized = 1;
}
// Zufallszahlen zwischen 1 und 2*len generieren (keine Duplikate)
unsigned int inserted = 0;
while (inserted < len)
{
// Zufallszahl zwischen 1 und 2*len generieren
unsigned int randomNum = (rand() % (2 * len)) + 1;
// In Baum einfügen und prüfen, ob Duplikat
int isDuplicate = 0;
tree = addToTree(tree, &randomNum, sizeof(unsigned int),
compareUnsignedInt, &isDuplicate);
// Wenn kein Duplikat, ins Array einfügen
if (!isDuplicate)
{
numbers[inserted] = randomNum;
inserted++;
}
}
// Baum aufräumen
clearTree(tree);
// Einen zufälligen Eintrag duplizieren
// Wähle zwei verschiedene Indizes
unsigned int sourceIndex = rand() % len;
unsigned int targetIndex;
do
{
targetIndex = rand() % len;
} while (targetIndex == sourceIndex);
// Kopiere Wert von source nach target (erzeugt Duplikat)
numbers[targetIndex] = numbers[sourceIndex];
return numbers;
}
// Findet das Duplikat durch Sortieren und Vergleich benachbarter Elemente
// Gibt 0 bei Fehlern zurück
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{
// Eingabevalidierung
if (numbers == NULL || len < 2)
{
return 0; // Fehler
}
// Kopie des Arrays erstellen (um Original nicht zu verändern)
unsigned int *sortedNumbers = (unsigned int *)malloc(len * sizeof(unsigned int));
if (sortedNumbers == NULL)
{
return 0; // Speicherfehler
}
// Array kopieren
memcpy(sortedNumbers, numbers, len * sizeof(unsigned int));
// Array mit qsort sortieren
qsort(sortedNumbers, len, sizeof(unsigned int), compareUnsignedInt);
// Benachbarte Elemente vergleichen, um Duplikat zu finden
unsigned int duplicate = 0;
for (unsigned int i = 0; i < len - 1; i++)
{
if (sortedNumbers[i] == sortedNumbers[i + 1])
{
duplicate = sortedNumbers[i];
break;
}
}
// Aufräumen
free(sortedNumbers);
return duplicate;
}