Commit 09e85e99 authored by schneefux's avatar schneefux

test

parents
Pipeline #4 failed with stages
in 32 minutes and 16 seconds
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>AlgoAufgabe1</groupId>
<artifactId>AlgoAufgabe1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package de.ostfalia.algo.ws18.base;
/**
* @author M. Gruendel
*/
public enum Gender {
M,
F
}
package de.ostfalia.algo.ws18.base;
/**
* @author M. Gruendel
*/
public interface IManagement {
/**
* Liefert die Anzahl der Datensaetze.
* @return Anzahl der Datensaetze: int.
*/
public int size();
/**
* Fuegt ein Mitglied dem Datensatz hinzu.
* @param member - hinzuzufuegendes Mitglied: IMember.
* @return true, wenn das Mitglied hinzugefuegt werden konnte, sonst
* false.
*/
public boolean insert(IMember member);
/**
* Sucht nach einem Datensatz mit dem angegebenen Schluessel.
* @param key - Schluesselwert: long
* @return - den gefundenen Datensatz, oder null, wenn der Schluesselwert
* nicht gefunden werden konnte: IMember.
*/
public IMember search(long key);
/**
* Sucht nach dem ersten Datensatz mit dem angegebenen Namen und Vornamen.
* @param name - Nachname des Mitglieds: String.
* @param firstName - Vorname des Mitglieds: String.
* @return - den gefundenen Datensatz, oder null, wenn der Schluesselwert
* nicht gefunden werden konnte: IMember.
*/
public IMember search(String name, String firstName);
/**
* Liefert die Anzahl der Datensaetze mit der angegebenen Sportart zurueck.
* @param kindOfSport die gesuchte Sportart: KindOfSport.
* @return - Anzahl der Datensaetze mit der angegebenen Sportart: int.
*/
public int size(KindOfSport kindOfSport);
/**
* Liefert die Datensaetze mit der angegebenen Sportart zurueck.
* @param kindOfSport die gesuchte Sportart: KindOfSport.
* @return - die Datensaetze mit der angegebenen Sportart: IMember[].
*/
public IMember[] discipline(KindOfSport kindOfSport);
/**
* Liefert alle Datensaetze als Array von IMember zurueck.
* @return - alle Datensaetze als Array: IMember[].
*/
public IMember[] toArray();
/**
* Liefert die Anzahl grundlegenden Operationen bei der zuvor aufgerufenen
* Zugriffsmethode zurueck.
* @return - Anzahl grundlegenden Operationen bei der zuvor aufgerufenen
* Zugriffsmethode: int.
*/
public int numberOfOperations();
/**
* Nur fuer Aufgabe 3: liefert die Hoehe des binaeren Suchbaums zurueck.
* @return - die Hoehe des binaeren Suchbaums: int.
*/
public default int height() {
return 0;
};
}
package de.ostfalia.algo.ws18.base;
import java.time.LocalDate;
/**
* @author M. Gruendel
*/
public interface IMember extends Comparable<IMember> {
/**
* Liefert den Schluesselwert zurueck.
* @return - den Schluesselwert: int.
*/
public long getKey();
/**
* Liefert den Nachnamen des Mitglieds zurueck.
* @return - den Nachnamen des Mitglieds: String.
*/
public String getName();
/**
* Liefert den Vornamen des Mitglieds zurueck.
* @return - den Vornamen des Mitglieds: String.
*/
public String getFirstName();
/**
* Liefert das Geschlecht des Mitglieds zurueck.
* @return Geschlecht des Mitglieds: Gender.
*/
public Gender getGender();
/**
* Liefert das Geburtsdatum des Mitglieds zurueck.
* @return Geburtsdatum des Mitglieds: LocalDate.
*/
public LocalDate getDate();
/**
* liefert die Sportart zurueck.
* @return - die Sportart: KindOfSport;
*/
public KindOfSport getKindOfSport();
/**
* Liefert den Datensatz inklusive Schluesselwert als String zurueck.<br><br>
* Beispiel: "82115101922, Hueber, Uta, 1922-10-15, F, HANDBALL"
* @return Datensatz inklusive Schluesselwert: String.
*/
public String toString();
}
package de.ostfalia.algo.ws18.base;
/**
* @author M. Gruendel
*/
public enum KindOfSport {
FUSSBALL,
HANDBALL,
SCHWIMMEN,
LEICHTATHLETIK,
REITEN,
FECHTEN,
TURNEN,
RADSPORT,
TANZEN,
RUDERN
}
package de.ostfalia.algo.ws18.base;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Member implements IMember {
/**
* Schlüssel kodiert als:
* Anfangsbuchstabe des Namens, codiert in
* zwei Dezimalziffern a -> 01, b -> 02, …, z -> 26.
* Diese Zuordnung gilt für Groß- und Kleinbuchstaben,
* Umlaute werden als ae, oe, ue dargestellt.
* Anfangsbuchstabe des Vornamens, codiert in
* zwei Dezimalziffern, siehe Name
* Geburtsdatum, ttmmjjjj
*
* Sie können davon ausgehen, dass doppelte Schlüssel nicht vorkommen.
*/
private long key;
/**
* Name.
*/
private String name;
/**
* Firstname.
*/
private String firstname;
/**
* Date.
*/
private LocalDate date;
/**
* Gender.
*/
private Gender gender;
/**
* Associated kind of sport.
*/
private KindOfSport kindOfSport;
/**
* Parse a CSV to a Member.
*
* @param csv A CSV String separated by ', ',
* with the row signature 'name, firstname, date, gender, kind of sport'
* @return A Member.
*/
public Member(String csv) {
final String DELIMITER = ", ";
String[] columns = csv.split(DELIMITER);
if (columns.length != 5) {
throw new IllegalArgumentException(
"Row '" + csv + "' is not a valid format!");
}
this.name = columns[0];
this.firstname = columns[1];
this.date = LocalDate.parse(columns[2],
DateTimeFormatter.ISO_DATE);
this.gender = Gender.valueOf(columns[3]);
this.kindOfSport = KindOfSport.valueOf(columns[4]);
this.key = encode(this);
}
/**
* Member constructor.
*
* @param name The name.
* @param firstname The firstname.
* @param date The date.
* @param gender The gender.
* @param kindOfSport The associated kind of sport.
*/
public Member(String name,
String firstname,
LocalDate date,
Gender gender,
KindOfSport kindOfSport) {
this.name = name;
this.firstname = firstname;
this.date = date;
this.gender = gender;
this.kindOfSport = kindOfSport;
this.key = encode(this);
}
/**
* Generate a unique key from a member's attributes.
*
* @param member A member.
* @return A key.
*/
private static Long encode(Member member) {
String nameKeyPart = encodeLetters(member.name.substring(0, 1));
String surnameKeyPart = encodeLetters(member.firstname.substring(0, 1));
String dateKeyPart = encodeDate(member.date);
String key = nameKeyPart + surnameKeyPart + dateKeyPart;
return Long.valueOf(key);
}
/**
* Format the given date as part of a key.
*
* @param date A LocalDate.
* @return A String ttmmjjjj.
*/
private static String encodeDate(LocalDate date) {
return String.format("%02d%02d%02d", // 2 digits, left pad
date.getDayOfMonth(),
date.getMonthValue(),
date.getYear());
}
/**
* Map each letter in the given string to a value
* between '01' and '26'.
*
* @param string A string containing only letters.
* @return A string of zero padded digits.
*/
private static String encodeLetters(String string) {
String encodedString = "";
for (char letter : sanitizeLetters(string).toCharArray()) {
int letterIndex = letter - 'a' + 1;
if (letterIndex < 1 || letterIndex > 26) {
throw new IllegalArgumentException(
letter + " cannot be encoded!");
}
encodedString += String.format("%02d", letterIndex);
}
return encodedString;
}
/**
* Replace ä, ö, ü and lowercase the string.
*
* @param string A string.
* @return A lowercase string without umlauts.
*/
private static String sanitizeLetters(String string) {
return string
.toLowerCase()
.replace("ä", "ae")
.replace("ö", "oe")
.replace("ü", "ue");
}
/**
* Return this member as string.
*/
@Override
public String toString() {
return this.key + ", "
+ this.name + ", "
+ this.firstname + ", "
+ this.date + ", "
+ this.gender + ", "
+ this.kindOfSport;
}
/**
* Implement the Comparable interface by comparing the keys.
*
* @return @see Comparable
*/
@Override
public int compareTo(IMember member) {
return Long.compare(this.key, member.getKey());
}
@Override
public String getName() {
return this.name;
}
@Override
public Gender getGender() {
return this.gender;
}
@Override
public LocalDate getDate() {
return this.date;
}
@Override
public String getFirstName() {
return this.firstname;
}
@Override
public long getKey() {
return this.key;
}
@Override
public KindOfSport getKindOfSport() {
return this.kindOfSport;
}
}
package de.ostfalia.algo.ws18.s1;
/**
* A generic linked list node.
*
* @param <E> The type of the value this node contains.
*/
public class LinkedListNode<E> {
/**
* This node's value.
*/
private E value;
/**
* The next linked node.
*/
private LinkedListNode<E> next;
/**
* Create a node with the given value and no next node.
*
* @param value This node's value.
*/
public LinkedListNode(E value) {
this.value = value;
this.next = null;
}
/**
* Get this node's value.
*
* @return This node's value.
*/
public E getValue() {
return this.value;
}
/**
* Set this node's value.
*
* @param value The new value.
*/
public void setValue(E value) {
this.value = value;
}
/**
* Get the next linked node.
*
* @return The next linked node.
*/
public LinkedListNode<E> getNext() {
return this.next;
}
/**
* Set the next linked node.
*
* @param next
*/
public void setNext(LinkedListNode<E> next) {
this.next = next;
}
}
package de.ostfalia.algo.ws18.s1;
import java.time.LocalDate;
import de.ostfalia.algo.ws18.base.Gender;
import de.ostfalia.algo.ws18.base.KindOfSport;
import de.ostfalia.algo.ws18.base.Member;
public class Main {
public static void main(String ...args) {
Management management = new Management();
management.checkpoint();
management.insert(new Member("Blümchen", "Benjamin", LocalDate.now(), Gender.M, KindOfSport.TANZEN));
System.out.println(management.checkpoint()/1000 + " ms für das erste insert");
management.insert(new Member("Kolumna", "Carla", LocalDate.now(), Gender.F, KindOfSport.RADSPORT));
System.out.println(management.checkpoint()/1000 + " ms für das zweite insert");
System.out.println("management hat " + management.size() + " Elemente, eingefügt in " + management.numberOfOperations());
management.checkpoint();
System.out.println("Suche Claudia Wexler: "
+ management.search("Wexler", "Claudia")
+ ", gefunden nach " + management.numberOfOperations()
+ " Operationen und " + management.checkpoint()/1000 + " ms");
}
}
package de.ostfalia.algo.ws18.s1;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.function.Predicate;
import de.ostfalia.algo.ws18.base.IManagement;
import de.ostfalia.algo.ws18.base.IMember;
import de.ostfalia.algo.ws18.base.KindOfSport;
import de.ostfalia.algo.ws18.base.Member;
public class Management implements IManagement {
/**
* Track the number of operations.
*/
protected int numberOfOperations;
/**
* Track the execution time.
*/
private long lastCheckpointNs;
/**
* Current head node.
*/
protected LinkedListNode<IMember> head;
/**
* Length of the list.
*/
protected int size = 0;
/**
* Whether the list is reversed, i. e. the head is the tail.
*/
private boolean reversed = false;
/**
* Empty constructor.
*/
public Management() {
}
/**
* Insert from an array of strings.
*
* @param membersCsv Array of CSV rows.
*/
public Management(String[] membersCsv) {
for (String memberCsv : membersCsv) {
this.insert(new Member(memberCsv));
}
}
/**
* Read from the CSV file and insert.
*
* @param filename Path to the CSV file.
*/
public Management(String filename) {
this.importFromFile(filename);
}
/**
* Read from the CSV file and insert.
*
* @param filename Path to the CSV file.
*/
public void importFromFile(String filename) {
File file = new File(filename);
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
bufferedReader.lines().forEach(line -> insert(new Member(line)));
} catch (IOException exception) {
throw new IllegalArgumentException(exception);
}
}
/**
* Create a filtered version of this list.
*
* @param criteria Criteria to filter for.
* @param breakAfterFirstMatch If true, return after the first match.
* @return A new list where all elements meet the given criteria.
*/
protected Management filter(Predicate<IMember> criteria, boolean breakAfterFirstMatch) {
Management result = new Management();
if (this.size == 0) {
return result;
}
// searches from head, inserts at head -> result is reversed
result.reverse();
LinkedListNode<IMember> currentNode = this.head;
do {
IMember currentValue = currentNode.getValue();
this.numberOfOperations++;
if (criteria.test(currentValue)) {
result.insert(currentValue);
if (breakAfterFirstMatch) {
break;
}
}
} while ((currentNode = currentNode.getNext()) != null);
return result;
}
/**
* Find the first element that matches the given criteria.
*
* @param criteria Criteria to search for.
* @return The first element that matches the given criteria or null.
*/
protected LinkedListNode<IMember> search(Predicate<IMember> criteria) {
Management filteredList = this.filter(criteria, true);
if (filteredList.size() == 0) {
return null;
} else {
return filteredList.head;
}
}
/**
* Count the number of elements that match the given criteria.
*
* @param criteria Criteria to filter for.
* @return The number of elements that match the given criteria.
*/
private long size(Predicate<IMember> criteria) {
return this.filter(criteria, false).size;
}
/**
* Reverse the order of the list.
*/
public void reverse() {
this.reversed = !this.reversed;
}
/**
* @return The length of this list.
*/
@Override
public int size() {
return this.size;
}
/**
* Add an element at the start of the list.
* Replace the current head with a new node and link this node to the old head.
*
* @return TODO?
*/
@Override
public boolean insert(IMember value) {
LinkedListNode<IMember> newHead = new LinkedListNode<IMember>(value);
this.numberOfOperations++;
if (this.head != null) {
newHead.setNext(this.head);
}
this.head = newHead;
this.size++;
return true; // TODO?
}
/**
* Find the first member with the given key.
*
* @param key The key to search for.
* @return The member or null.
*/
@Override
public IMember search(long key) {
LinkedListNode<IMember> result = this.search(member -> member.getKey() == key);
if (result != null) {
return result.getValue();
} else {
return null;
}
}
/**
* Find the first member with the given name.
*
* @param name The name of the member.
* @param firstName first name of the member.
* @return The member or null.
*/
@Override
public IMember search(String name, String firstName) {
LinkedListNode<IMember> result = this.search(member -> member.getName().equals(name)
&& member.getFirstName().equals(firstName));
if (result != null) {
return result.getValue();
} else {
return null;
}
}
/**
* Count the number of members which have an association to the given kindOfSport.
*
* @param kindOfSport The kindOfSport of the members.
* @return The number of members with the given kindOfSport.
*/
@Override
public int size(KindOfSport kindOfSport) {
this.numberOfOperations = 0;
return (int) this.size(member -> member.getKindOfSport().equals(kindOfSport));
}
/**
* Return the members which have an association to the given kindOfSport.
*
* @param kindOfSport The kindOfSport of the members.
* @return An array of the members with the given kindOfSport.
*/
@Override
public IMember[] discipline(KindOfSport kindOfSport) {
return this.filter(member -> member.getKindOfSport().equals(kindOfSport), false)
.toArray();
}
/**
* Convert the list to an array.
*
* @return The elements of this list as array.
*/
@Override