135 lines
3.9 KiB
C
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;
|
|
} |