97 lines
3.6 KiB
C
97 lines
3.6 KiB
C
#include "numbers.h"
|
|
#include "bintree.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
// 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.
|
|
|
|
// vergleicht zwei Werte: a<b: -1 a>b: 1 a=b: 0
|
|
int compareUnsignedInt(const void *a, const void *b) {
|
|
unsigned int x = *(unsigned int *)a;
|
|
unsigned int y = *(unsigned int *)b;
|
|
return (x < y) ? -1 : (x > y);
|
|
}
|
|
|
|
unsigned int *createNumbers(unsigned int len) {
|
|
if (len < 2) // Duplikat bei zwei Einträgen sinnlos
|
|
return NULL;
|
|
|
|
unsigned int *numbersArray = malloc(
|
|
sizeof(unsigned int) * len); // Speicher für das Ausgabearray reservieren:
|
|
// Größe eines Eintrags * Größe des Arrays
|
|
if (!numbersArray) // Speicher konnte nicht reserviert werden
|
|
return NULL;
|
|
|
|
TreeNode *root =
|
|
NULL; // Binärbaum zum Generieren der Zufallszahlen ohne Duplikate
|
|
|
|
for (unsigned int i = 0; i < len; i++) {
|
|
unsigned int currentNumber;
|
|
int isDuplicate;
|
|
do { // mindestens eine Zufallszahl erzeugen
|
|
currentNumber = (rand() % (2 * len)) + 1; // Zahlenbereich 1 bis 2*len
|
|
isDuplicate = 0;
|
|
root = addToTree(root, ¤tNumber, sizeof(unsigned int),
|
|
compareUnsignedInt,
|
|
&isDuplicate); // compareUnsignedInt wird zum Verwenden
|
|
// bei Vergleichen übergeben
|
|
} while (isDuplicate); // wenn isDuplicate gesetzt wird, muss eine neue Zahl
|
|
// erzeugt werden, die Schleife wird wiederholt
|
|
numbersArray[i] = currentNumber;
|
|
}
|
|
|
|
// Ein zufälliges Duplikat erzeugen
|
|
unsigned int duplicateIndex =
|
|
rand() % len; // Index des Duplikats per Zufall bestimmen
|
|
unsigned int newIndex;
|
|
do {
|
|
newIndex = rand() % len;
|
|
} while (newIndex == duplicateIndex); // zweiten Index bestimmen, der nicht
|
|
// mit dem ersten übereinstimmt
|
|
|
|
numbersArray[newIndex] =
|
|
numbersArray[duplicateIndex]; // Wert vom ersten Index kopieren
|
|
|
|
clearTree(&root); // Speicher wieder freigeben, wird nicht mehr benötigt
|
|
return numbersArray;
|
|
}
|
|
|
|
// Returns only the only number in numbers which is present twice. Returns zero
|
|
// on errors.
|
|
unsigned int getDuplicate(
|
|
const unsigned int *numbers,
|
|
unsigned int len) { // array numbers, sowie die Länge wird übergeben
|
|
if (!numbers || len < 2)
|
|
return 0; // fehlerhaftes Array
|
|
|
|
TreeNode *root = NULL; // leerer Baum
|
|
unsigned int duplicateValue = 0; // Wert des Duplikats
|
|
|
|
for (unsigned int i = 0; i < len && duplicateValue == 0; i++) { // Schleife
|
|
int isDuplicate = 0;
|
|
|
|
// Zahl in den Baum einfügen
|
|
root = addToTree(root, &numbers[i], sizeof(unsigned int),
|
|
compareUnsignedInt, &isDuplicate);
|
|
|
|
// Duplikat erkannt
|
|
if (isDuplicate && duplicateValue == 0) {
|
|
duplicateValue = numbers[i]; // Duplikat merken, for-Schleife wird beendet
|
|
}
|
|
}
|
|
|
|
clearTree(&root); // Baum freigeben
|
|
return duplicateValue; // 0, falls kein Duplikat
|
|
}
|