diff --git a/ws2019/ipi/uebungen/ipi6.pdf b/ws2019/ipi/uebungen/ipi6.pdf new file mode 100644 index 0000000..cb0c65a Binary files /dev/null and b/ws2019/ipi/uebungen/ipi6.pdf differ diff --git a/ws2019/ipi/uebungen/ipi6.tex b/ws2019/ipi/uebungen/ipi6.tex new file mode 100644 index 0000000..25693c6 --- /dev/null +++ b/ws2019/ipi/uebungen/ipi6.tex @@ -0,0 +1,75 @@ +\documentclass[uebung]{../../../lecture} + +\usepackage{listings} + +\title{Übungsblatt 6} +\author{Samuel Weidemaier, Christian Merten} + +\usepackage{xcolor} + +\lstdefinestyle{mystyle}{ + commentstyle=\color{gray}, + 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} + siehe Blatt. +\end{aufgabe} + +\begin{aufgabe} Primfaktorzerlegung + \begin{lstlisting}[language=C++, title=Primfaktorzerlegung, captionpos=b] +#include "cpp_headers/fcpp.hh" + +int main() { + int n = enter_int("Please enter a natural number: "); + // search smallest factor, start with smallest possible: 2 + int k=2; + // go until sqrt(n) + while (k <= sqrt(n)) { + // k is factor of n + if (n % k == 0) { + // print out the factor k + print(k); + // reset n to the quotient + n = n / k; + // restart at k=2 + k = 2; + } else { + // if k is not a factor, check next one + k++; + } + } + // n is the last prime factor of the original input number + print(n); +} + \end{lstlisting} + + Die algorithmische Komplexität des Programms für $n$ Primzahl ist $\sqrt{n}$, da die Schleife + für Primzahlen bis $\sqrt{n} $ durchlaufen wird. +\end{aufgabe} + +\begin{aufgabe} + siehe \textit{taschenrechner.cpp} + +\end{aufgabe} + +\end{document} diff --git a/ws2019/ipi/uebungen/primfaktorzerlegung.cpp b/ws2019/ipi/uebungen/primfaktorzerlegung.cpp new file mode 100644 index 0000000..f1d95e8 --- /dev/null +++ b/ws2019/ipi/uebungen/primfaktorzerlegung.cpp @@ -0,0 +1,26 @@ +#include "cpp_headers/fcpp.hh" + +int main() { + int n = enter_int("Please enter a natural number: "); + // search smallest factor, start with smallest possible: 2 + int k=2; + // go until sqrt(n) + while (k <= sqrt(n)) { + printf("searching for dividers for %d, checking %d\n", n, k); + // k is factor of n + if (n % k == 0) { + // print out the factor k + print(k); + // reset n to the quotient + n = n / k; + printf("found %d, setting n=%d\n", k, n); + // restart at k=2 + k = 2; + } else { + // if k is not a factor, check next one + k++; + } + } + // n is the last prime factor of the original input number + print(n); +} diff --git a/ws2019/ipi/uebungen/taschenrechner.cpp b/ws2019/ipi/uebungen/taschenrechner.cpp new file mode 100644 index 0000000..250275f --- /dev/null +++ b/ws2019/ipi/uebungen/taschenrechner.cpp @@ -0,0 +1,99 @@ +#include "cpp_headers/fcpp.hh" +#include // fuer strlen, Laenge eines C-Strings +#define MAX(a,b) a > b ? a : b // gibt stets die groeßere zahl zurueck + +// Taschenrechner Stack mit aktuellem Index und Zahlenspeicher +struct RechnerStack { + int current = 0; // zeigt auf das erste leere Element, anfangs 0 + int numbers[64]; // der Zahlenstack +}; + +// initialisiere den Stack +RechnerStack stack; + +// gibt das letzte Element zurück +int pop() { + // letztes Element ist eins vor dem ersten leeren + int last = stack.numbers[stack.current-1]; + // setze den alten Eintrag auf 0 + stack.numbers[stack.current-1] = 0; + // reduziere den Index um 1, aber falle nicht unter 0 + stack.current = MAX(stack.current-1, 0); + // gebe letztes Element zurueck + return last; +} + +// fuege ein Element dem Stack hinzu +void push(int element) { + stack.numbers[stack.current] = element; // setze letztes leeres auf neuen wert + stack.current += 1; // erhöhe den aktuellen Index +} + +int main(int argc, char* argv[]) { + // Setzen Sie hier auf einen leeren Stack + + // fange kein Kommandozeilenargument ab + if(argc < 2) { + print("Eingabe für den Taschenrechner erwartet!"); + return 1; + } + + // arg enthaelt die als Eingabe von der Kommandozeile uebergebene Zeichenfolge + char* arg = argv[1]; + + // Schleife, die die Zeichen der Eingabe nacheinander ablaeuft + // strlen gibt die Anzahl der Zeichen in der Zeichenkette + bool inNumber = false; // merkt, ob aktuell eine zahl eingelesen wird + int digitCount = 0; // zaehlt die anzahl der ziffern + for (int i = 0; i <= strlen(arg); i = i+1) { + char zeichen = arg[i]; // aktuelles Zeichen + // 48: 0, 49: 1, ..., 57: 9 in ASCII + if (zeichen >= 48 && zeichen <= 57) { + inNumber = true; // setze auf true, da gerade Zahl eingelesen wird + digitCount += 1; + push(zeichen - 48); // fuege die neue Ziffer dem stack hinzu + } else if (inNumber) { + // erstes Zeichen nach Ziffern, das keine Ziffer ist + inNumber = false; + int newNumber = 0; // summiere nun alle ziffern auf + for (int i = 0; i < digitCount; i++) { + // nehme ziffer vom stack und multipliziere sie mit der + // richtigen Zehnerpotenz fuer diese Dezimalstelle + newNumber += pop()*pow(10, i); + } + // fuege neue Zahl dem Stack hinzu + push(newNumber); + // setze Zifferzahl zurueck + digitCount = 0; + } if (zeichen == '+' || zeichen == '-' || zeichen == '*' || zeichen == '/') { + // falls zeichen ein Rechenoperator + if (stack.current < 2) { + // nicht genug argumente im stack fuer den operator + print("Invalid: Not enough arguments for operator!"); + return 1; + } + // nehme die zwei letzten Argumente + int b = pop(); // letztes Element + int a = pop(); // vorletztes Element + // und fuehre Operation auf a und b aus, je nach zeichen + // und fuege sie dem stack hinzu + if (zeichen == '+') { + push(a+b); + } else if (zeichen == '-') { + push(a-b); + } else if (zeichen == '*') { + push(a*b); + } else if (zeichen == '/') { + push(a/b); + } + } + } + if (stack.current > 1) { + // falls mehr als eine Zahl im Stack uebrig, + // haben Operatoren gefehlt, werfe also Fehler + print("Invalid: Not enough operators for argument"); + return 1; + } + // drucke das Ergebnis aus (letztes Element auf dem Stack) + print(pop()); +}