\documentclass[uebung]{../../../lecture}

\title{IPI: Übungsblatt 8}
\author{Samuel Weidemaier, Christian Merten}

\usepackage[]{listings}

\usepackage{xcolor}
 
\lstdefinestyle{mystyle}{
    commentstyle=\color{gray},
    language=C++,
    keywordstyle=\color{blue},
    numberstyle=\tiny\color{gray},
    stringstyle=\color{black},
    basicstyle=\ttfamily\footnotesize,
    breakatwhitespace=false,         
    breaklines=true,                 
    captionpos=b,                    
    keepspaces=true,                 
    numbers=left,                    
    numbersep=5pt,                  
    showspaces=false,                
    showstringspaces=false,
    showtabs=false,                  
    tabsize=2
}
 
\lstset{style=mystyle}


\begin{document}

\punkte

\begin{aufgabe} Konstruktoren

\begin{tabular}{llllllllllll}
    \textbf{37}: & a int-Konstruktor & b int-Konstruktor \\
    \textbf{38}: & c Copy-Konstruktor & d Konstruktor & e Konstruktor \\
    \textbf{39}: & d int-Zuweisung \\
    \textbf{40}: & T Copy-Konstruktor & T Addition & U int-Konstruktor & V Copy-Konstruktor
    & U Destruktor \\
    & W Copy-Konstruktor & V Destruktor & d Zuweisung & W Destruktor & T Destruktor\\
    \textbf{41}: & d Addition & T int-Konstruktor & U Copy-Konstruktor & T Destruktor & U Addition \\
    & V int-Konstruktor & W Copy-Konstruktor & V Destruktor & e Zuweisung & W Destruktor\\
    & U Destruktor \\
    \textbf{42}: & e Destruktor & d Destruktor & c Destruktor & b Destruktor & a Destruktor \\
\end{tabular}

\end{aufgabe}

\begin{aufgabe}
    \begin{enumerate}[(a)]
        \item Der Implementierung liegt weiterhin eine einfach verkettete Liste zu Grunde. Konkret
            wird die \lstinline{struct IntListElem} verwendet.
            
            Es wird ein Zeiger \lstinline{IntListElem* first} auf das erste Listenelement, eine
            Variable \lstinline{int count}, die die Länge der Liste speichert und zwei Hilfsmethoden,
            \lstinline{IntListElem* getListElement(int position)}, die einen Zeiger auf das interne
            Listenelement zurückgibt und \lstinline{void copy(IntList& other)}, die die Listenelemente
            von einer anderen Liste kopiert, verwendet.

            Der leere Konstruktor setzt \lstinline{first} und \lstinline{count} auf 0, genauso wie
            der Destruktor. Dies führt zur Initialisierung bzw. Leerung der Liste. Der Copy-Konstruktor
            bzw. Zuweisungsoperator initialisieren bzw. leeren die Liste ebenfalls zunächst und
            kopieren dann mithilfe der \lstinline{copy} Methode, die Elemente einer zweiten Liste.
        \item 

    \begin{lstlisting}[language=C++, title=listclass.cpp, captionpos=b]
#include<stdio.h>

// a list element
struct IntListElem {
    int value; // int value
    IntListElem* next; // pointer to the next element
};

// A list of integers
// Beware: indexing is done starting from 1 as the excercise sheet requests it
class IntList {
public:
    // empty constructor, creates an empty list
    IntList();
    
    // copy constructor, intializes by copying from 'other'
    IntList(IntList& other);

    // assignment operator, removes own elements and copies from 'other'
    IntList& operator=(IntList& other);

    // destructor, removes list content
    ~IntList();

    // returns the number of elements in the list
    int getCount();

    // returns if the list is empty
    bool isEmpty();

    // prints the list
    void print();

    // inserts 'element' in the beginning of the list
    void insert(int element);

    // inserts 'element' AFTER 'position'
    void insert(int element, int position);

    // removes the element AFTER 'position'
    void remove(int position);

    // returns the element AT 'position'
    int getElement(int position);
private:
    // pointer to first element
    IntListElem* first;    
    // element count
    int count;

    // returns the IntListElem AT 'position'
    IntListElem* getListElement(int position);

    // Kopiert die Liste 'other'
    void copy(IntList& other);
};

// creates new empty list
IntList::IntList() {
    first = 0;
    count = 0;
}

// creates a new list by copying an old one
IntList::IntList(IntList& list) {
    copy(list);
}

// Assignment operator
IntList& IntList::operator=(IntList& other) {
    if (this == &other) { // if assigning to the same object
        return *this; // do nothing
    }
    copy(other); // otherwise copy contents
    return *this; 
}

// destroys the list
IntList::~IntList() {
    first = 0; // remove the connection to the list elements
    count = 0; // reset list count
};

// private helper that copies from 'other' list
void IntList::copy(IntList& other) {
    // clear and copy elements
    first = 0;
    count = 0;
    // copy element by element from 'other' to this new list
    for (int i = 1; i <= other.count; i++) {
        insert(other.getElement(i), i-1);
    }
}

// private helper that returns the list element struct AT 'position'
IntListElem* IntList::getListElement(int position) {
    IntListElem* current = first;
    for (int i = 1; i < position; i++) {
        // if list is not long enough
        if (current->next == 0) {
            // return the last element
            return current;
        }
        current = current->next;
    }
    return current;
}

// return element AT 'position'
int IntList::getElement(int position) {
    if (position < 1 || position > count) {
        printf("Error: Index out of Bounds, no element at position %d\n", position);
        return -1;
    }
    return getListElement(position)->value; // return the value of the element
}

// insert 'element' AFTER 'position'
void IntList::insert(int element, int position) {
    if (position < 0 || position > count) { // check for invalid positions
        printf("Error: Index out of Bounds, can't insert.\n");
        return;
    }
    IntListElem* elem = new IntListElem(); // create a new list element
    elem->value = element; // with the given value
    if (position == 0) { // insert in the very beginning
        elem->next = first; // the successor of elem is the old first, now second element
        first = elem; // make the new element the new first
    } else {
        IntListElem* where = getListElement(position); // find the element to insert after
        elem->next = where->next; // make the old successor of where now follow elem
        where->next = elem; // make elem the new successor of where
    }
    count += 1;
    return;
}

// insert 'element' in the very beginning of the list
void IntList::insert(int element) {
    insert(element, 0); // insert AFTER position 0
}

// remove next element AFTER 'position'
void IntList::remove(int position) {
    if (position < 0 || position >= count) { // check for invalid positions
        printf("Error: Index out of bounds, can't remove after %d\n", position);
        return;
    }
    if (position == 0) { // remove first element
        first = first->next; // new first is the new element
    } else {
        IntListElem* where = getListElement(position); // find the element to remove after
        where->next = where->next->next; // remove by skipping the next element of where
    }
    count -= 1; // reduce element count
    return;
}

// check if list is empty
bool IntList::isEmpty() {
    return count == 0;
}

// returns the list's size
int IntList::getCount() {
    return count;
}

// print a list of integers
void IntList::print() {
    printf("["); // opening brackets
    IntListElem* current = first;
    while (current != 0) { // while not last element
        printf("%d", current->value); // print value
        if (current->next != 0) {
            printf(", "); // if not the last element, append a comma
        }
        current = current->next; // go to next
    }
    printf("]\n"); // closing brackets
}

int main() {
    IntList list;
    list.insert(30);
    list.insert(20);
    list.insert(10);
    list.print();

    list.remove(2);
    list.print();

    list.insert(30,2);
    list.print();

    list.insert(40,3);
    list.print();

    IntList copy(list);
    copy.print();

    copy.remove(0);
    copy.print();
    list.print();

    copy = list;
    copy.print();

    return 0;
}
    \end{lstlisting}
    \end{enumerate}
\end{aufgabe}

\end{document}
