commit e21da561fcc034edbb32a5eb63234c9bd1c318e6 Author: christian Date: Wed Nov 6 18:20:14 2019 +0100 add cpp headers and first uebung program diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f86b60 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +* + +!*.* +!*/ diff --git a/ws2019/ipi/cpp_headers/ASCII.cc b/ws2019/ipi/cpp_headers/ASCII.cc new file mode 100644 index 0000000..1f1bb7e --- /dev/null +++ b/ws2019/ipi/cpp_headers/ASCII.cc @@ -0,0 +1,7 @@ +#include "fcpp.hh" + +int main () +{ + for (int i=32; i<=127; i=i+1) + print(i,(char) i,0); +} diff --git a/ws2019/ipi/cpp_headers/Adder4bit.hh b/ws2019/ipi/cpp_headers/Adder4bit.hh new file mode 100644 index 0000000..0d26f2d --- /dev/null +++ b/ws2019/ipi/cpp_headers/Adder4bit.hh @@ -0,0 +1,25 @@ +class Adder4Bit : public Circuit { +public: + Adder4Bit (); + // Konstruktor + + ~Adder4Bit (); + // destruktor + + virtual void ChangeInput (State s, int pin); + // Eingang wechselt zur aktuellen Zeit den Zustand + + virtual void Action (); + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + + virtual void ConnectInput (Wire& w, int pin); + // verdrahte Eingang + + virtual void ConnectOutput (Wire& w, int pin); + // verdrahte Ausgang + +private: + Wire w0,w1,w2; // lokale Draehte + FullAdder fa0,fa1,fa2,fa3; // Volladdierer +} ; diff --git a/ws2019/ipi/cpp_headers/Adder4bitImp.cc b/ws2019/ipi/cpp_headers/Adder4bitImp.cc new file mode 100644 index 0000000..b2c6499 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Adder4bitImp.cc @@ -0,0 +1,50 @@ +Adder4Bit::Adder4Bit() +{ + w0.ConnectInput(fa0,1); + w0.ConnectOutput(fa1,0); + w1.ConnectInput(fa1,1); + w1.ConnectOutput(fa2,0); + w2.ConnectInput(fa2,1); + w2.ConnectOutput(fa3,0); +} + +Adder4Bit::~Adder4Bit() {} + +void Adder4Bit::ChangeInput (State s, int pin) +{ + if (pin==0) fa0.ChangeInput(s,1); + if (pin==1) fa1.ChangeInput(s,1); + if (pin==2) fa2.ChangeInput(s,1); + if (pin==3) fa3.ChangeInput(s,1); + if (pin==4) fa0.ChangeInput(s,2); + if (pin==5) fa1.ChangeInput(s,2); + if (pin==6) fa2.ChangeInput(s,2); + if (pin==7) fa3.ChangeInput(s,2); + if (pin==8) fa0.ChangeInput(s,0); +} + +void Adder4Bit::Action () {} + +void Adder4Bit::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) fa0.ConnectInput(w,1); + if (pin==1) fa1.ConnectInput(w,1); + if (pin==2) fa2.ConnectInput(w,1); + if (pin==3) fa3.ConnectInput(w,1); + if (pin==4) fa0.ConnectInput(w,2); + if (pin==5) fa1.ConnectInput(w,2); + if (pin==6) fa2.ConnectInput(w,2); + if (pin==7) fa3.ConnectInput(w,2); + if (pin==8) fa0.ConnectInput(w,0); +} + +void Adder4Bit::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) fa0.ConnectOutput(w,0); + if (pin==1) fa1.ConnectOutput(w,0); + if (pin==2) fa2.ConnectOutput(w,0); + if (pin==3) fa3.ConnectOutput(w,0); + if (pin==4) fa3.ConnectOutput(w,1); +} diff --git a/ws2019/ipi/cpp_headers/AdderBeispiel.cc b/ws2019/ipi/cpp_headers/AdderBeispiel.cc new file mode 100644 index 0000000..770725b --- /dev/null +++ b/ws2019/ipi/cpp_headers/AdderBeispiel.cc @@ -0,0 +1,89 @@ +#include +#include +#include"DLL.hh" +#include"MinPriorityQueue.hh" +#include"MinPriorityQueueImp.cc" +#include"Queue.hh" +class Simulator; // forward declaration +class Wire; // forward declaration +class Circuit; // forward declaration +#include"Wire.hh" +#include"Circuit.hh" +#include"Simulator.hh" +#include"SimulatorImp.cc" +#include"WireImp.cc" +#include"Nand.hh" +#include"NandImp.cc" +#include"And.hh" +#include"AndImp.cc" +#include"Nor.hh" +#include"NorImp.cc" +#include"Or.hh" +#include"OrImp.cc" +#include"Exor.hh" +#include"ExorImp.cc" +#include"Inverter.hh" +#include"InverterImp.cc" +#include"Fork.hh" +#include"ForkImp.cc" +#include"Terminal.hh" +#include"TerminalImp.cc" +#include"Analyzer.hh" +#include"AnalyzerImp.cc" +#include"Clock.hh" +#include"ClockImp.cc" +#include"HalfAdder.hh" +#include"HalfAdderImp.cc" +#include"FullAdder.hh" +#include"FullAdderImp.cc" +#include"Adder4Bit.hh" +#include"Adder4BitImp.cc" + +int main () +{ + Adder4Bit adder; + Analyzer analyzer(5); + Terminal a3(low ),a2(high),a1(high),a0(high); + Terminal b3(high),b2(low ),b1(high),b0(low ); + Terminal c0(low); + + Wire wa0,wa1,wa2,wa3; + Wire wb0,wb1,wb2,wb3; + Wire ws0,ws1,ws2,ws3; + Wire wc0,wc4; + + wc0.ConnectInput(c0,0); + wc0.ConnectOutput(adder,8); + + wa0.ConnectInput(a0,0); + wa1.ConnectInput(a1,0); + wa2.ConnectInput(a2,0); + wa3.ConnectInput(a3,0); + wa0.ConnectOutput(adder,0); + wa1.ConnectOutput(adder,1); + wa2.ConnectOutput(adder,2); + wa3.ConnectOutput(adder,3); + + wb0.ConnectInput(b0,0); + wb1.ConnectInput(b1,0); + wb2.ConnectInput(b2,0); + wb3.ConnectInput(b3,0); + wb0.ConnectOutput(adder,4); + wb1.ConnectOutput(adder,5); + wb2.ConnectOutput(adder,6); + wb3.ConnectOutput(adder,7); + + ws0.ConnectInput(adder,0); + ws1.ConnectInput(adder,1); + ws2.ConnectInput(adder,2); + ws3.ConnectInput(adder,3); + ws0.ConnectOutput(analyzer,0); + ws1.ConnectOutput(analyzer,1); + ws2.ConnectOutput(analyzer,2); + ws3.ConnectOutput(analyzer,3); + + wc4.ConnectInput(adder,4); + wc4.ConnectOutput(analyzer,4); + + Sim.Simulate(40); +} diff --git a/ws2019/ipi/cpp_headers/Analyzer.hh b/ws2019/ipi/cpp_headers/Analyzer.hh new file mode 100644 index 0000000..2e55233 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Analyzer.hh @@ -0,0 +1,29 @@ +class Analyzer : public Circuit { +public: + Analyzer (int m); + // Konstruktor + + ~Analyzer (); + // Destruktor + + virtual void ChangeInput (State s, int pin); + // Eingang wechselt zur aktuellen Zeit den Zustand + + virtual void Action (); + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + + virtual void ConnectInput (Wire& w, int pin); + // verdrahte Eingang + + virtual void ConnectOutput (Wire& w, int pin); + // verdrahte Ausgang + +private: + int n; // Anzahl Eingaenge + Wire** a; // Die n Eingangsdraehte + Wire* b; // Engang fuer Selbstaktivierung + Wire* c; // Ausgang fuer Selbstaktivierung + bool actionFlag; // merke ob bereits aktiviert + Wire w; // Draht fuer Selbstaktivierung +} ; diff --git a/ws2019/ipi/cpp_headers/AnalyzerImp.cc b/ws2019/ipi/cpp_headers/AnalyzerImp.cc new file mode 100644 index 0000000..e6df057 --- /dev/null +++ b/ws2019/ipi/cpp_headers/AnalyzerImp.cc @@ -0,0 +1,64 @@ +Analyzer::Analyzer (int m) +{ + n = m; // Merke Groesse, Eingang n + a = new Wire*[n]; // n Zeiger auf Wires + for (int i=0; i Draht + w.ConnectOutput(*this,n); // Draht->Ich + actionFlag=true; // nix aktiviert + Sim.StoreCircuitEvent(*this); // Starte Auswertung +} + +Analyzer::~Analyzer() +{ + delete[] a; +} + +void Analyzer::ChangeInput (State s, int pin) +{ + // Sorge dafuer, dass Gatter neu berechnet wird, wenn + // alle Zustaende der Eingaenge (Draehte) festliegen + if (!actionFlag) + { + Sim.StoreCircuitEvent(*this); + actionFlag=true; + } +} + +void Analyzer::Action () +{ + // Lese Eingangssignale + std::cout.width(10); + std::cout << Sim.GetTime(); + for (int i=n-1; i>=0; i=i-1) + if (a[i]!=0) + { + if (a[i]->GetState()==low) std::cout << " 0"; + if (a[i]->GetState()==high) std::cout << " 1"; + if (a[i]->GetState()==unknown) std::cout << " U"; + } + else std::cout << " "; + std::cout << std::endl; + + // Selbstaktivierung im naechsten Zeitschritt + if (c->GetState()==unknown) c->ChangeState(Sim.GetTime()+1,high); + if (c->GetState()==low) c->ChangeState(Sim.GetTime()+1,high); + if (c->GetState()==high) c->ChangeState(Sim.GetTime()+1,low); + + // erlaube neue Auswertung + actionFlag=false; +} + +void Analyzer::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin>=0 && pinGetState(); + State B = b->GetState(); + State Output=unknown; + + // Wertetabelle + if (A==high&& B==high) Output=high; + if (A==low || B==low ) Output=low; + + // Setze Draht + if (c!=0) c->ChangeState(Sim.GetTime()+3,Output); + + // erlaube neue Auswertung + actionFlag=false; +} + +void And::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) a = &w; + if (pin==1) b = &w; +} + +void And::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + c = &w; +} diff --git a/ws2019/ipi/cpp_headers/Array.hh b/ws2019/ipi/cpp_headers/Array.hh new file mode 100644 index 0000000..8d7918b --- /dev/null +++ b/ws2019/ipi/cpp_headers/Array.hh @@ -0,0 +1,96 @@ +template class Array { +public: + typedef T MemberType; // Merke Grundtyp + + // Iterator fuer die Feld-Klasse + class Iterator { + private: + T* p; // Iterator ist ein Zeiger ... + Iterator(T* q) {p=q;} + public: + Iterator() {p=0;} + bool operator!= (Iterator x) { + return (p!=x.p); + } + bool operator== (Iterator x) { + return (p==x.p); + } + Iterator operator++ () { + p++; + return *this; + } + Iterator operator++ (int) { + Iterator tmp = *this; + ++*this; + return tmp; + } + T& operator* () const {return *p;} + T* operator-> () const {return p;} + friend class Array; + } ; + + // Iterator Methoden + Iterator begin () const { + return Iterator(p); + } + Iterator end () const { + return Iterator(&(p[n])); // ja, das ist ok! + } + + // Konstruktion; Destruktion und Zuweisung + Array(int m) { + n = m; + p = new T[n]; + } + Array (const Array&); + Array& operator= (const Array&); + ~Array() { + delete[] p; + } + + // Array manipulation + int size () const { + return n; + } + T& operator[](int i) { + return p[i]; + } + +private: + int n; // Anzahl Elemente + T *p; // Zeiger auf built-in array +} ; + +// Copy-Konstruktor +template +Array::Array (const Array& a) { + n = a.n; + p = new T[n]; + for (int i=0; i +Array& Array::operator= (const Array& a) { + if (&a!=this) { + if (n!=a.n) { + delete[] p; + n = a.n; + p = new T[n]; + } + for (int i=0; i +std::ostream& operator<< (std::ostream& s, Array& a) { + s << "array " << a.size() << + " elements = [" << std::endl; + for (int i=0; iBand::N) + { + print("Band zu klein"); + return; + } + for (int i=0; i=benutzt) benutzt = pos+1; + pos = pos-1; +} + +void Band::schreibe_rechts (char symbol) +{ + if (pos>=Band::N-1) + { + print("Versuch ueber rechtes Bandende zu laufen!"); + return; + } + + band[pos] = symbol; + if (pos>=benutzt) benutzt = pos+1; + pos = pos+1; +} + +void Band::drucke () +{ + char kopie[N+3]; + int j=0; + for (int i=0; i +int binsearch (C& a, typename C::value_type x) +{ // returns either index (if found) or -1 + int l = 0; + int r = a.size(); + while (1) { + int m = (l+r)/2; + if (m==l) + return (a[m]==x) ? m : -1; + if (x +void bubblesort (C& a) { + for (int i=a.size()-1; i>=0; i--) + for (int j=0; j + +int main () +{ + std::string vorname = "Peter"; + std::string nachname = "Bastian"; + std::string name = vorname + " " + nachname; + print(name); +} + diff --git a/ws2019/ipi/cpp_headers/CheckedSimpleFloatArray.hh b/ws2019/ipi/cpp_headers/CheckedSimpleFloatArray.hh new file mode 100644 index 0000000..d6da146 --- /dev/null +++ b/ws2019/ipi/cpp_headers/CheckedSimpleFloatArray.hh @@ -0,0 +1,11 @@ +class CheckedSimpleFloatArray : + public SimpleFloatArray { +public: + CheckedSimpleFloatArray (int s, float f); + + // Default-Versionen von copy Konstruktor, Zuweisungsoperator + // und Destruktor sind OK + + // Indizierter Zugriff mit Indexprüfung + float& operator[](int i); +} ; diff --git a/ws2019/ipi/cpp_headers/CheckedSimpleFloatArrayImp.cc b/ws2019/ipi/cpp_headers/CheckedSimpleFloatArrayImp.cc new file mode 100644 index 0000000..9b9e65c --- /dev/null +++ b/ws2019/ipi/cpp_headers/CheckedSimpleFloatArrayImp.cc @@ -0,0 +1,9 @@ +CheckedSimpleFloatArray::CheckedSimpleFloatArray (int s, float f) + : SimpleFloatArray (s,f) +{} + +float& CheckedSimpleFloatArray::operator[] (int i) +{ + assert (i>=minIndex() && i<=maxIndex()); + return SimpleFloatArray::operator[](i); +} diff --git a/ws2019/ipi/cpp_headers/Circuit.hh b/ws2019/ipi/cpp_headers/Circuit.hh new file mode 100644 index 0000000..7b1dc67 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Circuit.hh @@ -0,0 +1,19 @@ +class Circuit { +public: + // virtual destructor + virtual ~Circuit (); + + // (F): Eingang wechselt Zustand + virtual void ChangeInput (State s, int pin) = 0; + + // (C): Ausgang neu berechnen + virtual void Action () = 0; + + // verdrahte Eingang + virtual void ConnectInput (Wire& w, int pin) = 0; + + // verdrahte Ausgang + virtual void ConnectOutput (Wire& w, int pin) = 0; +} ; + +Circuit::~Circuit () {} diff --git a/ws2019/ipi/cpp_headers/Clock.hh b/ws2019/ipi/cpp_headers/Clock.hh new file mode 100644 index 0000000..5e081a5 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Clock.hh @@ -0,0 +1,30 @@ +class Clock : public Circuit { +public: + Clock (int m, State initial); + // Konstruktor + + ~Clock (); + // Destruktor + + virtual void ChangeInput (State s, int pin); + // Eingang wechselt zur aktuellen Zeit den Zustand + + virtual void Action (); + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + + virtual void ConnectInput (Wire& w, int pin); + // verdrahte Eingang + + virtual void ConnectOutput (Wire& w, int pin); + // verdrahte Ausgang + +private: + State init; // erster Zustand + int n; // Taktrate + Wire* a; // Eingang Selbstaktivierung + Wire* b; // Ausgang fuer Selbstaktivierung + Wire* c; // Ausgang fuer Taktsignal + bool actionFlag; // merke ob bereits aktiviert + Wire w; // Draht fuer Selbstaktivierung +} ; diff --git a/ws2019/ipi/cpp_headers/ClockImp.cc b/ws2019/ipi/cpp_headers/ClockImp.cc new file mode 100644 index 0000000..06eab76 --- /dev/null +++ b/ws2019/ipi/cpp_headers/ClockImp.cc @@ -0,0 +1,59 @@ +Clock::Clock (int m, State initial) +{ + init = initial; // Merken + n = m; // Merke Taktrate + a = b = c = 0; // nix angeschlossen + actionFlag=false; // nix aktiviert + w.ConnectInput(*this,1); // Ich -> Draht + w.ConnectOutput(*this,0); // Draht->Ich + Sim.StoreCircuitEvent(*this); +} + +Clock::~Clock() {} + +void Clock::ChangeInput (State s, int pin) +{ + // Sorge dafuer, dass Gatter neu berechnet wird, wenn + // alle Zustaende der Eingaenge (Draehte) festliegen + if (!actionFlag) + { + Sim.StoreCircuitEvent(*this); + actionFlag=true; + } +} + +void Clock::Action () +{ + // Selbstaktivierung nach n Takten + if (c->GetState()==unknown) + { + c->ChangeState(Sim.GetTime()+1,init); + b->ChangeState(Sim.GetTime()+1,init); + } + if (c->GetState()==low) + { + c->ChangeState(Sim.GetTime()+n,high); + b->ChangeState(Sim.GetTime()+n,high); + } + if (c->GetState()==high) + { + c->ChangeState(Sim.GetTime()+n,low); + b->ChangeState(Sim.GetTime()+n,low); + } + + // erlaube neue Auswertung + actionFlag=false; +} + +void Clock::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + a = &w; +} + +void Clock::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) b = &w; + if (pin==1) c = &w; +} diff --git a/ws2019/ipi/cpp_headers/Complex2.cc b/ws2019/ipi/cpp_headers/Complex2.cc new file mode 100644 index 0000000..6ed99c3 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Complex2.cc @@ -0,0 +1,37 @@ +#include "fcpp.hh" + +struct Complex { + float real; + float imag; +} ; + +Complex erzeuge_complex (float re, float im) +{ + Complex t; + t.real = re; t.imag = im; + return t; +} +float real (Complex q) {return q.real;} +float imag (Complex q) {return q.imag;} + +Complex add_complex (Complex p, Complex q) +{ + return erzeuge_complex(real(p) + real(q), + imag(p) + imag(q)); +} + +// etc + +void drucke_complex (Complex p) +{ + print(real(p),"+i*",imag(p),0); +} + +int main () +{ + Complex p = erzeuge_complex(3.0,4.0); + Complex q = erzeuge_complex(5.0,3.0); + drucke_complex(p); + drucke_complex(q); + drucke_complex(add_complex(p,q)); +} diff --git a/ws2019/ipi/cpp_headers/Cstring.cc b/ws2019/ipi/cpp_headers/Cstring.cc new file mode 100644 index 0000000..c9a93fc --- /dev/null +++ b/ws2019/ipi/cpp_headers/Cstring.cc @@ -0,0 +1,10 @@ +#include "fcpp.hh" + +int main () +{ + char name[32] = "Peter Bastian"; + + for (int i=0; name[i]!=0; i=i+1) + print(name[i]); // einzelne Zeichen + print(name); // ganze Zeichenkette +} diff --git a/ws2019/ipi/cpp_headers/DFA.cc b/ws2019/ipi/cpp_headers/DFA.cc new file mode 100644 index 0000000..7764b1c --- /dev/null +++ b/ws2019/ipi/cpp_headers/DFA.cc @@ -0,0 +1,40 @@ +class DynamicFloatArray : public FloatArray { +public: + DynamicFloatArray () {n=0; o=0; p=new float[1];} + + virtual ~DynamicFloatArray() {delete[] p;} + virtual float& operator[](int i); + virtual int numIndices () {return n;} + int minIndex () {return o;} + int maxIndex () {return o+n-1;} + bool isMember (int i) {return (i>=o)&&(i=o+n) + { // resize + int new_o, new_n; + if (i +class DLList { + + // das interne Listenelement + struct Element { + Element* next; + Element* prev; + T item; + Element (T &t) { + item = t; + next = prev = 0; + } + }; + +public: + typedef T MemberType; // Merke Grundtyp + + // der iterator kapselt Zeiger auf Listenelement + class Iterator { + private: + Element* p; + public: + Iterator () { p=0; } + Iterator (Element* q) { p=q; } + bool operator!= (Iterator x) { + return p!=x.p; + } + bool operator== (Iterator x) { + return p==x.p; + } + Iterator operator++ () { // prefix + p=p->next; + return *this; + } + Iterator operator++ (int) { // postfix + Iterator tmp = *this; + p=p->next; + return tmp; + } + Iterator operator-- () { // prefix + p=p->prev; + return *this; + } + Iterator operator-- (int) { // postfix + Iterator tmp = *this; + p=p->prev; + return tmp; + } + T& operator* () { return p->item; } + T* operator-> () { return &(p->item); } + friend class DLList; // Liste man. p + } ; + + // Iteratoren + Iterator begin () const {return head;} + Iterator end () const {return Iterator();} + Iterator rbegin () const {return tail;} + Iterator rend () const {return Iterator();} + + // Konstruktion, Destruktion, Zuweisung + DLList (); + DLList (const DLList& list); + DLList& operator= (const DLList&); + ~DLList(); + + // Listenmanipulation + Iterator insert (Iterator i, T t);// einf. vor i + void erase (Iterator i); + void append (const DLList& l); + void clear (); + bool empty () const; + int size () const; + Iterator find (T t) const; + +private: + Iterator head; // erstes Element der Liste + Iterator tail; // letztes Element der Liste +} ; + + +// Insertion +template +typename DLList::Iterator +DLList::insert (Iterator i, T t) +{ + Element* e = new Element(t); + if (empty()) + { + assert(i.p==0); + head.p = tail.p = e; + } + else + { + e->next = i.p; + if (i.p!=0) + { // insert before i + e->prev = i.p->prev; + i.p->prev = e; + if (head==i) + head.p=e; + } + else + { // insert at end + e->prev = tail.p; + tail.p->next = e; + tail.p = e; + } + } + return Iterator(e); +} + +template +void DLList::erase (Iterator i) +{ + if (i.p==0) return; + + if (i.p->next!=0) + i.p->next->prev = i.p->prev; + if (i.p->prev!=0) + i.p->prev->next = i.p->next; + + if (head==i) head.p=i.p->next; + if (tail==i) tail.p=i.p->prev; + + delete i.p; +} + +template +void DLList::append (const DLList& l) { + for (Iterator i=l.begin(); i!=l.end(); i++) + insert(end(),*i); +} + +template +bool DLList::empty () const { + return begin()==end(); +} + +template +void DLList::clear () { + while (!empty()) + erase(begin()); +} + +// Constructors +template DLList::DLList () {} + +template +DLList::DLList (const DLList& list) { + append(list); +} + +// Assignment +template +DLList& +DLList::operator= (const DLList& l) { + if (this!=&l) { + clear(); + append(l); + } + return *this; +} + +// Destructor +template DLList::~DLList() { clear(); } + +// Size method +template int DLList::size () const { + int count = 0; + for (Iterator i=begin(); i!=end(); i++) + count++; + return count; +} + +template +typename DLList::Iterator DLList::find (T t) const { + DLList::Iterator i = begin(); + while (i!=end()) + { + if (*i==t) break; + i++; + } + return i; +} + +template +std::ostream& operator<< (std::ostream& s, DLList& a) { + s << "("; + for (typename DLList::Iterator i=a.begin(); + i!=a.end(); i++) + { + if (i!=a.begin()) s << " "; + s << *i; + } + s << ")" << std::endl; + return s; +} diff --git a/ws2019/ipi/cpp_headers/DeQueue.hh b/ws2019/ipi/cpp_headers/DeQueue.hh new file mode 100644 index 0000000..b9a2a41 --- /dev/null +++ b/ws2019/ipi/cpp_headers/DeQueue.hh @@ -0,0 +1,12 @@ +template +class DeQueue : private DLList { +public : + // Default-Konstruktoren + Zuweisung ok + bool empty (); + void push_front (T t); + void push_back (T t); + T pop_front (); + T pop_back (); + T front (); + T back (); +} ; diff --git a/ws2019/ipi/cpp_headers/Exor.hh b/ws2019/ipi/cpp_headers/Exor.hh new file mode 100644 index 0000000..2bf3cdd --- /dev/null +++ b/ws2019/ipi/cpp_headers/Exor.hh @@ -0,0 +1,27 @@ +class Exor : public Circuit { +public: + Exor (); + // Konstruktor + + ~Exor (); + // default destructor ist OK + + virtual void ChangeInput (State s, int pin); + // Eingang wechselt zur aktuellen Zeit den Zustand + + virtual void Action (); + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + + virtual void ConnectInput (Wire& w, int pin); + // verdrahte Eingang + + virtual void ConnectOutput (Wire& w, int pin); + // verdrahte Ausgang + +private: + Wire* a; // Eingang 1 + Wire* b; // Eingang 2 + Wire* c; // Ausgang + bool actionFlag; // merke ob bereits aktiviert +} ; diff --git a/ws2019/ipi/cpp_headers/ExorImp.cc b/ws2019/ipi/cpp_headers/ExorImp.cc new file mode 100644 index 0000000..d6b87c9 --- /dev/null +++ b/ws2019/ipi/cpp_headers/ExorImp.cc @@ -0,0 +1,51 @@ +Exor::Exor() +{ + a=b=c=0; // nix angschlossen + actionFlag=false; +} + +Exor::~Exor() {} + +void Exor::ChangeInput (State s, int pin) +{ + // Sorge dafuer, dass Gatter neu berechnet wird, wenn + // alle Zustaende der Eingaenge (Draehte) festliegen + if (!actionFlag) + { + Sim.StoreCircuitEvent(*this); + actionFlag=true; + } +} + +void Exor::Action () +{ + // Lese Eingangssignale + State A = a->GetState(); + State B = b->GetState(); + + // Wertetabelle + if (A==low && B==low) c->ChangeState(Sim.GetTime()+3,low); + if (A==low && B==high) c->ChangeState(Sim.GetTime()+3,high); + if (A==high&& B==low) c->ChangeState(Sim.GetTime()+3,high); + if (A==high&& B==high) c->ChangeState(Sim.GetTime()+3,low); + + // unbekannt + if (A==unknown||B==unknown) + if (c!=0) c->ChangeState(Sim.GetTime()+3,unknown); + + // erlaube neue Auswertung + actionFlag=false; +} + +void Exor::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) a = &w; + if (pin==1) b = &w; +} + +void Exor::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + c = &w; +} diff --git a/ws2019/ipi/cpp_headers/Experiment.cc b/ws2019/ipi/cpp_headers/Experiment.cc new file mode 100644 index 0000000..1cb2dfb --- /dev/null +++ b/ws2019/ipi/cpp_headers/Experiment.cc @@ -0,0 +1,27 @@ +class Experiment { +public: + Experiment (Zufall& z); // Konstruktor + int durchfuehren (); // einmal ausfuehren +private: + Zufall& zg; // Merke Zufallsgenerator + unsigned int ggT (unsigned int a, + unsigned int b); +} ; + +Experiment::Experiment (Zufall& z) : zg(z) {} + +unsigned int Experiment::ggT (unsigned int a, unsigned int b) +{ + if (b==0) return a; + else return ggT(b,a%b); +} + +int Experiment::durchfuehren () +{ + unsigned int x1 = zg.ziehe_zahl(); + unsigned int x2 = zg.ziehe_zahl(); + if (ggT(x1,x2)==1) + return 1; + else + return 0; +} diff --git a/ws2019/ipi/cpp_headers/FloatArray.hh b/ws2019/ipi/cpp_headers/FloatArray.hh new file mode 100644 index 0000000..9951d9c --- /dev/null +++ b/ws2019/ipi/cpp_headers/FloatArray.hh @@ -0,0 +1,10 @@ +class FloatArray { +public: + virtual ~FloatArray() {}; + virtual float& operator[](int i) = 0; + virtual int numIndices () = 0; + virtual int minIndex () = 0; + virtual int maxIndex () = 0; + virtual bool isMember (int i) = 0; +} ; + diff --git a/ws2019/ipi/cpp_headers/Fork.hh b/ws2019/ipi/cpp_headers/Fork.hh new file mode 100644 index 0000000..c16aa6f --- /dev/null +++ b/ws2019/ipi/cpp_headers/Fork.hh @@ -0,0 +1,26 @@ +class Fork : public Circuit { +public: + // Konstruktor + Fork (); + + // default destructor ist OK + ~Fork (); + + // Eingang wechselt zur aktuellen Zeit den Zustand + virtual void ChangeInput (State s, int pin); + + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + virtual void Action (); + + // verdrahte Eingang + virtual void ConnectInput (Wire& w, int pin); + + // verdrahte Ausgang + virtual void ConnectOutput (Wire& w, int pin); + +private: + Wire* a; // Eingang + Wire* b; // Ausgang 1 + Wire* c; // Ausgang 2 +} ; diff --git a/ws2019/ipi/cpp_headers/ForkImp.cc b/ws2019/ipi/cpp_headers/ForkImp.cc new file mode 100644 index 0000000..cb63d23 --- /dev/null +++ b/ws2019/ipi/cpp_headers/ForkImp.cc @@ -0,0 +1,31 @@ +Fork::Fork() +{ + a=b=c=0; // nix angschlossen +} + +Fork::~Fork() {} + +void Fork::ChangeInput (State s, int pin) +{ + // Leite Eingang SOFORT an beide Ausgaenge weiter + if (b!=0) b->ChangeState(Sim.GetTime(),s); + if (c!=0) c->ChangeState(Sim.GetTime(),s); +} + +void Fork::Action () +{ + // nix zu tun +} + +void Fork::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + a = &w; +} + +void Fork::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) b = &w; + if (pin==1) c = &w; +} diff --git a/ws2019/ipi/cpp_headers/FullAdder.hh b/ws2019/ipi/cpp_headers/FullAdder.hh new file mode 100644 index 0000000..676baf1 --- /dev/null +++ b/ws2019/ipi/cpp_headers/FullAdder.hh @@ -0,0 +1,26 @@ +class FullAdder : public Circuit { +public: + FullAdder (); + // Konstruktor + + ~FullAdder (); + // destruktor + + virtual void ChangeInput (State s, int pin); + // Eingang wechselt zur aktuellen Zeit den Zustand + + virtual void Action (); + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + + virtual void ConnectInput (Wire& w, int pin); + // verdrahte Eingang + + virtual void ConnectOutput (Wire& w, int pin); + // verdrahte Ausgang + +private: + Wire w1,w2,w3; // lokale Draehte + Or A; // Und Gatter + HalfAdder ha1,ha2; // Halbaddierer +} ; diff --git a/ws2019/ipi/cpp_headers/FullAdderImp.cc b/ws2019/ipi/cpp_headers/FullAdderImp.cc new file mode 100644 index 0000000..88634ef --- /dev/null +++ b/ws2019/ipi/cpp_headers/FullAdderImp.cc @@ -0,0 +1,35 @@ +FullAdder::FullAdder() +{ + w1.ConnectInput(ha1,0); + w1.ConnectOutput(ha2,0); + w2.ConnectInput(ha1,1); + w2.ConnectOutput(A,0); + w3.ConnectInput(ha2,1); + w3.ConnectOutput(A,1); +} + +FullAdder::~FullAdder() {} + +void FullAdder::ChangeInput (State s, int pin) +{ + if (pin==0) ha2.ChangeInput(s,1); + if (pin==1) ha1.ChangeInput(s,1); + if (pin==2) ha1.ChangeInput(s,0); +} + +void FullAdder::Action () {} + +void FullAdder::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) ha2.ConnectInput(w,1); + if (pin==1) ha1.ConnectInput(w,1); + if (pin==2) ha1.ConnectInput(w,0); +} + +void FullAdder::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) ha2.ConnectOutput(w,0); + if (pin==1) A.ConnectOutput(w,0); +} diff --git a/ws2019/ipi/cpp_headers/Funktional-statisch.cc b/ws2019/ipi/cpp_headers/Funktional-statisch.cc new file mode 100644 index 0000000..59bbd27 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Funktional-statisch.cc @@ -0,0 +1,29 @@ +#include +using namespace std; + +class Inkrementierer { +public: + Inkrementierer (int n) {inkrement = n;} + int operator() (int n) {return n+inkrement;} +private: + int inkrement; +}; + +class Quadrat { +public: + int operator() (int n) {return n*n;} +} ; + +template +void schleife (T& func) { + for (int i=1; i<10; i++) + cout << func(i) << " "; + cout << endl; +} + +int main () { + Inkrementierer ink(10); + Quadrat quadrat; + schleife(ink); + schleife(quadrat); +} diff --git a/ws2019/ipi/cpp_headers/Funktor.cc b/ws2019/ipi/cpp_headers/Funktor.cc new file mode 100644 index 0000000..f757da7 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Funktor.cc @@ -0,0 +1,34 @@ +#include + +class Function { +public: + virtual ~Function () {}; + virtual int operator() (int) = 0; +}; + +class Inkrementierer : public Function { +public: + Inkrementierer (int n) {inkrement = n;} + int operator() (int n) {return n+inkrement;} +private: + int inkrement; +}; + +void schleife (Function& func) { + for (int i=1; i<10; i++) + std::cout << func(i) << " "; + std::cout << std::endl; +} + +class Quadrat : public Function { +public: + int operator() (int n) {return n*n;} +} ; + +int main () { + Inkrementierer ink(10); + Quadrat quadrat; + schleife (ink); + schleife (quadrat); +} + diff --git a/ws2019/ipi/cpp_headers/HalfAdder.hh b/ws2019/ipi/cpp_headers/HalfAdder.hh new file mode 100644 index 0000000..762f68e --- /dev/null +++ b/ws2019/ipi/cpp_headers/HalfAdder.hh @@ -0,0 +1,27 @@ +class HalfAdder : public Circuit { +public: + // Konstruktor + HalfAdder (); + + // destruktor + ~HalfAdder (); + + // Eingang wechselt zur aktuellen Zeit den Zustand + virtual void ChangeInput (State s, int pin); + + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + virtual void Action (); + + // verdrahte Eingang + virtual void ConnectInput (Wire& w, int pin); + + // verdrahte Ausgang + virtual void ConnectOutput (Wire& w, int pin); + +private: + Wire w1,w2,w3,w4,w5,w6,w7; // lokale Draehte + And A; // Und Gatter + Nor N1,N2; // sowie zwei Nor Gatter + Fork F1,F2,F3; // und drei Verzweigungen +} ; diff --git a/ws2019/ipi/cpp_headers/HalfAdderImp.cc b/ws2019/ipi/cpp_headers/HalfAdderImp.cc new file mode 100644 index 0000000..9573c77 --- /dev/null +++ b/ws2019/ipi/cpp_headers/HalfAdderImp.cc @@ -0,0 +1,41 @@ +HalfAdder::HalfAdder() +{ + w1.ConnectInput(F1,1); + w1.ConnectOutput(A,0); + w2.ConnectInput(F1,0); + w2.ConnectOutput(N1,0); + w3.ConnectInput(F2,0); + w3.ConnectOutput(A,1); + w4.ConnectInput(F2,1); + w4.ConnectOutput(N1,1); + w5.ConnectInput(N1,0); + w5.ConnectOutput(N2,1); + w6.ConnectInput(A,0); + w6.ConnectOutput(F3,0); + w7.ConnectInput(F3,0); + w7.ConnectOutput(N2,0); +} + +HalfAdder::~HalfAdder() {} + +void HalfAdder::ChangeInput (State s, int pin) +{ + if (pin==0) F1.ChangeInput(s,0); + if (pin==1) F2.ChangeInput(s,0); +} + +void HalfAdder::Action () {} + +void HalfAdder::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) F1.ConnectInput(w,0); + if (pin==1) F2.ConnectInput(w,0); +} + +void HalfAdder::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) N2.ConnectOutput(w,0); + if (pin==1) F3.ConnectOutput(w,1); +} diff --git a/ws2019/ipi/cpp_headers/Heap.hh b/ws2019/ipi/cpp_headers/Heap.hh new file mode 100644 index 0000000..c7f3a14 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Heap.hh @@ -0,0 +1,54 @@ +template +class Heap { +public: + bool empty (); + void push (T x); + void pop (); + T top (); +private: + std::vector data; + void reheap (int i); +} ; + +template +void Heap::push (T x) { + int i = data.size(); + data.push_back(x); + while (i>0 && data[i]>data[(i-1)/2]) + { + std::swap(data[i],data[(i-1)/2]); + i = (i-1)/2; + } +} + +template +void Heap::reheap (int i) { + int n = data.size(); + while (2*i+1data[l])) ? r : l; + if (data[k]<=data[i]) break; + std::swap(data[k], data[i]); + i = k; + } +} + +template +void Heap::pop () { + std::swap(data.front(), data.back()); + data.pop_back(); + reheap(0); +} + +template +T Heap::top () { + return data[0]; +} + +template +inline bool Heap::empty () { + return data.size()==0; +} + diff --git a/ws2019/ipi/cpp_headers/Heapsort.cc b/ws2019/ipi/cpp_headers/Heapsort.cc new file mode 100644 index 0000000..8567491 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Heapsort.cc @@ -0,0 +1,25 @@ +template +inline void reheap (C& a, int n, int i) { + while (2*i+1a[l])) ? r : l; + if (a[k]<=a[i]) break; + std::swap(a[k], a[i]); + i = k; + } +} + +template +void heapsort (C& a) +{ + // build the heap by reheaping from the rear + for (int i=a.size()-1; i>=0; i--) + reheap(a, a.size(), i); + // build the sorted list by popping the heap + for (int i=a.size()-1; i>=0; i--) { + std::swap(a[0],a[i]); + reheap(a, i, 0); + } +} diff --git a/ws2019/ipi/cpp_headers/HuffmanSTL.cc b/ws2019/ipi/cpp_headers/HuffmanSTL.cc new file mode 100644 index 0000000..01c4f80 --- /dev/null +++ b/ws2019/ipi/cpp_headers/HuffmanSTL.cc @@ -0,0 +1,115 @@ +#include +#include +#include +#include + +using namespace std; // import namespace std + +// There are no general binary trees in the STL. +// But we do not use much of this structure anyhow... +struct node { + struct node *left; + struct node *right; + char symbol; + int weight; + node (char c, int i) { // leaf constructor + symbol = c; + weight = i; + left = right = 0; + } + node (node* l, node *r) { // internal node constructor + symbol = 0; + weight = l->weight + r->weight; + left = l; + right = r; + } + bool isleaf() {return symbol!=0;} + bool operator> (const node &a) const { + return weight > a.weight; + } +}; + +// construct the Huffman trie for this message +node* huffman_trie (string message) { + // count multiplicities + map cmap; + for (string::iterator i=message.begin(); i!=message.end(); i++) + if (cmap.find(*i)!=cmap.end()) + cmap[*i]++; + else + cmap[*i]=1; + + // generate leaves with multiplicities + priority_queue, greater > q; + for (map::iterator i=cmap.begin(); i!=cmap.end(); i++) + q.push(node(i->first,i->second)); + + // build Huffman tree (trie) + while (q.size()>1) + { + node *left = new node(q.top()); + q.pop(); + node *right = new node(q.top()); + q.pop(); + q.push(node(left, right)); + } + return new node(q.top()); +} + +// recursive filling of the encoding table 'code' +void fill_encoding_table (string s, node *i, + map& code) { + if (i->isleaf()) + code[i->symbol]=s; + else + { + fill_encoding_table (s+"0", i->left, code); + fill_encoding_table (s+"1", i->right, code); + } +} + +// encoding +string encode (map code, string& message) { + string encoded = ""; + for (string::iterator i=message.begin(); i!=message.end(); i++) + encoded += code[*i]; + return encoded; +} + +// decoding +string decode (node* trie, string& encoded) { + string decoded = ""; + node* node = trie; + for (string::iterator i=encoded.begin(); i!=encoded.end(); i++) + { + if (!node->isleaf()) + node = (*i=='0') ? node->left : node->right; + if (node->isleaf()) + { + decoded.push_back(node->symbol); + node = trie; + } + } + return decoded; +} + +int main () { + string message = "ABRACADABRASIMSALABIM"; + + // generate Huffman trie + node* trie = huffman_trie(message); + + // generate and show encoding table + map table; + fill_encoding_table ("", trie, table); + for (map::iterator i=table.begin(); i!=table.end(); i++) + cout << i->first << " " << i->second << endl; + + // encode and decode + string encoded = encode(table, message); + cout << "Encoded: " << encoded << + " [" << encoded.size() << " Bits]" << endl ; + cout << "Decoded: " << decode(trie, encoded) << endl; + + // the trie is not deleted here ... +} diff --git a/ws2019/ipi/cpp_headers/Inkrementierer.cc b/ws2019/ipi/cpp_headers/Inkrementierer.cc new file mode 100644 index 0000000..7f08be5 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Inkrementierer.cc @@ -0,0 +1,20 @@ +#include "fcpp.hh" // fuer print + +class Inkrementierer { +public: + Inkrementierer (int n) {inkrement = n;} + int eval (int n) {return n+inkrement;} +private: + int inkrement; +}; + +void schleife (Inkrementierer &ink) { + for (int i=1; i<10; i++) + print(ink.eval(i)); +} + +int main () { + Inkrementierer ink(10); + schleife (ink); +} + diff --git a/ws2019/ipi/cpp_headers/Insertionsort.cc b/ws2019/ipi/cpp_headers/Insertionsort.cc new file mode 100644 index 0000000..91ff47c --- /dev/null +++ b/ws2019/ipi/cpp_headers/Insertionsort.cc @@ -0,0 +1,11 @@ +template +void insertionsort (C& a) { + for (int i=1; i0 && a[j-1]>a[j]) { + std::swap(a[j], a[j-1]); + j=j-1; + } + } +} diff --git a/ws2019/ipi/cpp_headers/Inverter.hh b/ws2019/ipi/cpp_headers/Inverter.hh new file mode 100644 index 0000000..618c211 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Inverter.hh @@ -0,0 +1,26 @@ +class Inverter : public Circuit { +public: + Inverter (); + // Konstruktor + + ~Inverter (); + // default destructor ist OK + + virtual void ChangeInput (State s, int pin); + // Eingang wechselt zur aktuellen Zeit den Zustand + + virtual void Action (); + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + + virtual void ConnectInput (Wire& w, int pin); + // verdrahte Eingang + + virtual void ConnectOutput (Wire& w, int pin); + // verdrahte Ausgang + +private: + Wire* a; // Eingang + Wire* b; // Ausgang + bool actionFlag; // merke ob bereits aktiviert +} ; diff --git a/ws2019/ipi/cpp_headers/InverterImp.cc b/ws2019/ipi/cpp_headers/InverterImp.cc new file mode 100644 index 0000000..7cb8d2f --- /dev/null +++ b/ws2019/ipi/cpp_headers/InverterImp.cc @@ -0,0 +1,46 @@ +Inverter::Inverter() +{ + a=b=0; // nix angschlossen + actionFlag=false; +} + +Inverter::~Inverter() {} + +void Inverter::ChangeInput (State s, int pin) +{ + // Sorge dafuer, dass Gatter neu berechnet wird, wenn + // alle Zustaende der Eingaenge (Draehte) festliegen + if (!actionFlag) + { + Sim.StoreCircuitEvent(*this); + actionFlag=true; + } +} + +void Inverter::Action () +{ + // Lese Eingangssignale + State A = a->GetState(); + State Output=unknown; + + // Wertetabelle + if (A==low ) Output=high; + if (A==high) Output=low; + + if (b!=0) b->ChangeState(Sim.GetTime()+3,Output); + + // erlaube neue Auswertung + actionFlag=false; +} + +void Inverter::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + a = &w; +} + +void Inverter::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + b = &w; +} diff --git a/ws2019/ipi/cpp_headers/Konto.cc b/ws2019/ipi/cpp_headers/Konto.cc new file mode 100644 index 0000000..90d7021 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Konto.cc @@ -0,0 +1,40 @@ +#include "fcpp.hh" + +class Konto { +public: + Konto (int start); // Konstruktor + ~Konto (); // Destruktor + int kontostand (); + int abheben (int betrag); +private: + int bilanz; +} ; + +Konto::Konto (int startkapital) +{ + bilanz = startkapital; + print("Konto mit ",bilanz," eingerichtet",0); +} + +Konto::~Konto () +{ + print("Konto mit ",bilanz," aufgelöst",0); +} + +int Konto::kontostand () { + return bilanz; +} + +int Konto::abheben (int betrag) +{ + bilanz = bilanz - betrag; + return bilanz; +} + +int main () +{ + Konto k1(100), k2(200); + + k1.abheben(50); + k2.abheben(300); +} diff --git a/ws2019/ipi/cpp_headers/LFA.cc b/ws2019/ipi/cpp_headers/LFA.cc new file mode 100644 index 0000000..bb60b0f --- /dev/null +++ b/ws2019/ipi/cpp_headers/LFA.cc @@ -0,0 +1,104 @@ +class ListFloatArray : + public FloatArray { // Ableitung +public: + ListFloatArray (); // leeres Feld + + ~ListFloatArray(); // ersetzt ~FloatArray + + virtual float& operator[](int i); + virtual int numIndices (); + virtual int minIndex (); + virtual int maxIndex (); + virtual bool isMember (int i); +private: + struct FloatListElem { // lokale Struktur + FloatListElem *next; + int index; + float value; + }; + FloatListElem* insert (int i, float v); + FloatListElem* find (int i); + + int n; // Anzahl Elemente + FloatListElem *p;// Listenanfang +} ; + +// private Hilfsfunktionen +ListFloatArray::FloatListElem* +ListFloatArray::insert (int i, float v) +{ + FloatListElem* q = new FloatListElem; + + q->index = i; + q->value = v; + q->next = p; + p = q; + n = n+1; + return q; +} + +ListFloatArray::FloatListElem* +ListFloatArray::find (int i) +{ + for (FloatListElem* q=p; q!=0; q = q->next) + if (q->index==i) + return q; + return 0; +} + +// Konstruktor +ListFloatArray::ListFloatArray () +{ + n = 0; // alles leer + p = 0; +} + +// Destruktor +ListFloatArray::~ListFloatArray () +{ + FloatListElem* q; + + while (p!=0) + { + q = p; // q ist erstes + p = q->next; // entferne q aus Liste + delete q; + } +} + +float& ListFloatArray::operator[] (int i) +{ + FloatListElem* r=find(i); + if (r==0) + r=insert(i,0.0); // index einfuegen + return r->value; +} + +int ListFloatArray::numIndices () +{ + return n; +} + +int ListFloatArray::minIndex () +{ + if (p==0) return 0; + int min=p->index; + for (FloatListElem* q=p->next; + q!=0; q = q->next) + if (q->indexindex; + return min; +} + +int ListFloatArray::maxIndex () +{ + if (p==0) return 0; + int max=p->index; + for (FloatListElem* q=p->next; + q!=0; q = q->next) + if (q->index>max) max=q->index; + return max; +} + +bool ListFloatArray::isMember (int i) { + return (find(i)!=0); +} diff --git a/ws2019/ipi/cpp_headers/LSBeispiel.cc b/ws2019/ipi/cpp_headers/LSBeispiel.cc new file mode 100644 index 0000000..403f860 --- /dev/null +++ b/ws2019/ipi/cpp_headers/LSBeispiel.cc @@ -0,0 +1,41 @@ +#include +#include +#include"DLL.hh" +#include"MinPriorityQueue.hh" +#include"MinPriorityQueueImp.cc" +#include"Queue.hh" +class Simulator; // forward declaration +class Wire; // forward declaration +class Circuit; // forward declaration +#include"Wire.hh" +#include"Circuit.hh" +#include"Simulator.hh" +#include"SimulatorImp.cc" +#include"WireImp.cc" +#include"Nand.hh" +#include"NandImp.cc" +#include"Terminal.hh" +#include"TerminalImp.cc" +#include"Fork.hh" +#include"ForkImp.cc" +#include"Analyzer.hh" +#include"AnalyzerImp.cc" +#include"Clock.hh" +#include"ClockImp.cc" + +int main () +{ + Nand nand1; Analyzer analyzer(3); + Fork fork1,fork2; Clock clock(10,high); + Wire a,b,c,d,e,f,g; Terminal term(high); + + a.ConnectInput(term,0); a.ConnectOutput(fork1,0); + b.ConnectInput(clock,0); b.ConnectOutput(fork2,0); + c.ConnectInput(fork1,0); c.ConnectOutput(nand1,0); + d.ConnectInput(fork1,1); d.ConnectOutput(analyzer,0); + e.ConnectInput(fork2,0); e.ConnectOutput(nand1,1); + f.ConnectInput(fork2,1); f.ConnectOutput(analyzer,1); + g.ConnectInput(nand1,0); g.ConnectOutput(analyzer,2); + + Sim.Simulate(33); +} diff --git a/ws2019/ipi/cpp_headers/ListFloatArrayDerived.hh b/ws2019/ipi/cpp_headers/ListFloatArrayDerived.hh new file mode 100644 index 0000000..44546fd --- /dev/null +++ b/ws2019/ipi/cpp_headers/ListFloatArrayDerived.hh @@ -0,0 +1,32 @@ +class ListFloatArray : + public FloatArray { // Ableitung +public: + // Konstruktoren + ListFloatArray (); // leeres Feld + + // Destruktor + ~ListFloatArray(); // ersetzt ~FloatArray !! + + // Indizierung + virtual float& operator[](int i); + + // allgemeine Indexmenge + virtual int numIndices (); + virtual int minIndex (); + virtual int maxIndex (); + virtual bool isMember (int i); + +private: + // lokal in der Klasse benutzte Datenstruktur + struct FloatListElem { + struct FloatListElem *next; // naechstes Element + int index; // der Index + float value; // der Wert + }; + + int n; // Anzahl Elemente + FloatListElem *p; // einfach verkettete Liste + + FloatListElem* insert (int i, float v); // Fuege in Liste ein + FloatListElem* find (int i); // finde Index +} ; diff --git a/ws2019/ipi/cpp_headers/ListFloatArrayImp.cc b/ws2019/ipi/cpp_headers/ListFloatArrayImp.cc new file mode 100644 index 0000000..e42ac13 --- /dev/null +++ b/ws2019/ipi/cpp_headers/ListFloatArrayImp.cc @@ -0,0 +1,81 @@ +// private Hilfsfunktionen +ListFloatArray::FloatListElem* ListFloatArray::insert (int i, float v) +{ + FloatListElem* q = new FloatListElem; + + q->index = i; + q->value = v; + q->next = p; + p = q; + n = n+1; + return q; +} + +ListFloatArray::FloatListElem* ListFloatArray::find (int i) +{ + for (FloatListElem* q=p; q!=0; q = q->next) + if (q->index==i) + return q; + return 0; +} + +// Konstruktoren +ListFloatArray::ListFloatArray () +{ + n = 0; // alles leer + p = 0; +} + +// Destruktor +ListFloatArray::~ListFloatArray () +{ + FloatListElem* q; + + while (p!=0) + { + q = p; // q ist erstes + p = q->next; // entferne q aus Liste + delete q; + } +} + +float& ListFloatArray::operator[] (int i) +{ + FloatListElem* r=find(i); + if (r==0) + r=insert(i,0.0); // erzeuge index, r nicht mehr 0 + return r->value; +} + +int ListFloatArray::numIndices () +{ + return n; +} + +int ListFloatArray::minIndex () +{ + if (p==0) return 0; + int min=p->index; + for (FloatListElem* q=p->next; q!=0; q = q->next) + if (q->indexindex; + return min; +} + +int ListFloatArray::maxIndex () +{ + if (p==0) return 0; + int max=p->index; + for (FloatListElem* q=p->next; q!=0; q = q->next) + if (q->index>max) max=q->index; + return max; +} + +bool ListFloatArray::isMember (int i) +{ + FloatListElem* r=find(i); + + if (r!=0) + return true; + else + return false; +} diff --git a/ws2019/ipi/cpp_headers/Liste.hh b/ws2019/ipi/cpp_headers/Liste.hh new file mode 100644 index 0000000..f5876a0 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Liste.hh @@ -0,0 +1,73 @@ +template +class List { +public: + // Infrastruktur + List() { _first=0; } + ~List(); + + // Listenelement als nested class + class Link { + Link* _next; + public: + T item; + Link (T& t) {item=t;} + Link* next () {return _next;} + friend class List; + }; + + Link* first() {return _first;} + void insert (Link* where, T t); + void remove (Link* where); + +private: + Link* _first; + // privater Copy-Konstruktor und Zuweisungs- + // operator da Defaultvarianten zu fehlerhaftem + // Verhalten fuehren + List (const List& l) {}; + List& operator= (const List& l) {}; +}; + +template List::~List() +{ + Link* p = _first; + while (p!=0) + { + Link* q = p; + p = p->next(); + delete q; + } +} + +template +void List::insert (List::Link* where, T t) +{ + Link* ins = new Link(t); + if (where==0) + { + ins->_next = _first; + _first = ins; + } + else + { + ins->_next = where->_next; + where->_next = ins; + } +} + +template +void List::remove (List::Link* where) +{ + Link* p; + if (where==0) + { + p = _first; + if (p!=0) _first = p->_next; + } + else + { + p = where->_next; + if (p!=0) where->_next = p->_next; + } + delete p; +} diff --git a/ws2019/ipi/cpp_headers/Map.hh b/ws2019/ipi/cpp_headers/Map.hh new file mode 100644 index 0000000..e89ee57 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Map.hh @@ -0,0 +1,18 @@ +// Existiert schon als std::pair +// template +// struct pair { +// Key first; +// T second; +// } ; + +template +class Map : private DLList > { +public : + + T& operator[](const Key& k); + + typedef typename DLList >::Iterator Iterator; + Iterator begin () const; + Iterator end () const; + Iterator find (const Key& k); +} ; diff --git a/ws2019/ipi/cpp_headers/Mergesort.cc b/ws2019/ipi/cpp_headers/Mergesort.cc new file mode 100644 index 0000000..0c43b50 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Mergesort.cc @@ -0,0 +1,29 @@ +template +void rec_merge_sort (C& a, int o, int n) +{ // sortiere Eintraege [o,o+n-1] + if (n==1) return; + + // teile und sortiere rekursiv + int n1=n/2; + int n2=n-n1; + rec_merge_sort(a,o,n1); + rec_merge_sort(a,o+n1,n2); + + // zusammenfuegen + C b(n); // Hilfsfeld + int i1=o, i2=o+n1; + for (int k=0; k=o+n) || (i1 +void mergesort (C& a) +{ + rec_merge_sort(a,0,a.size()); +} diff --git a/ws2019/ipi/cpp_headers/MinPriorityQueue.hh b/ws2019/ipi/cpp_headers/MinPriorityQueue.hh new file mode 100644 index 0000000..f00f992 --- /dev/null +++ b/ws2019/ipi/cpp_headers/MinPriorityQueue.hh @@ -0,0 +1,11 @@ +template +class MinPriorityQueue : public DLList { +private: + typename DLList::Iterator find_minimum(); +public : + // Default-Konstruktoren + Zuweisung OK + bool empty (); + void push (T t); // Einfuegen + void pop (); // Entferne kleinstes + T top (); // Inspiziere kleinstes +} ; diff --git a/ws2019/ipi/cpp_headers/MinPriorityQueueImp.cc b/ws2019/ipi/cpp_headers/MinPriorityQueueImp.cc new file mode 100644 index 0000000..48287a1 --- /dev/null +++ b/ws2019/ipi/cpp_headers/MinPriorityQueueImp.cc @@ -0,0 +1,29 @@ +template +bool MinPriorityQueue::empty () { + return DLList::empty(); +} + +template +void MinPriorityQueue::push (T t) { + this->insert(DLList::begin(),t); +} + +template +typename DLList::Iterator +MinPriorityQueue::find_minimum () { + typename DLList::Iterator min=DLList::begin(); + for (typename DLList::Iterator i=DLList::begin(); + i!=DLList::end(); i++) + if (*i<*min) min=i; + return min; +} + +template +inline void MinPriorityQueue::pop () { + this->erase(find_minimum()); +} + +template +inline T MinPriorityQueue::top () { + return *find_minimum(); +} diff --git a/ws2019/ipi/cpp_headers/MonteCarlo.cc b/ws2019/ipi/cpp_headers/MonteCarlo.cc new file mode 100644 index 0000000..6fe69e4 --- /dev/null +++ b/ws2019/ipi/cpp_headers/MonteCarlo.cc @@ -0,0 +1,21 @@ +#include "fcpp.hh" // fuer print +#include "Zufall.cc" // Code fuer die beiden +#include "Experiment.cc" // Klassen hereinziehen + +double montecarlo (Experiment& e, int N) +{ + int erfolgreich=0; + + for (int i=0; iGetState(); + State B = b->GetState(); + State Output=unknown; + + // Wertetabelle + if (A==high&& B==high) Output=low; + if (A==low || B==low ) Output=high; + + // Setze Draht + if (c!=0) c->ChangeState(Sim.GetTime()+3,Output); + + // erlaube neue Auswertung + actionFlag=false; +} + +void Nand::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) a = &w; + if (pin==1) b = &w; +} + +void Nand::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + c = &w; +} diff --git a/ws2019/ipi/cpp_headers/Nor.hh b/ws2019/ipi/cpp_headers/Nor.hh new file mode 100644 index 0000000..d5c6910 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Nor.hh @@ -0,0 +1,27 @@ +class Nor : public Circuit { +public: + Nor (); + // Konstruktor + + ~Nor (); + // default destructor ist OK + + virtual void ChangeInput (State s, int pin); + // Eingang wechselt zur aktuellen Zeit den Zustand + + virtual void Action (); + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + + virtual void ConnectInput (Wire& w, int pin); + // verdrahte Eingang + + virtual void ConnectOutput (Wire& w, int pin); + // verdrahte Ausgang + +private: + Wire* a; // Eingang 1 + Wire* b; // Eingang 2 + Wire* c; // Ausgang + bool actionFlag; // merke ob bereits aktiviert +} ; diff --git a/ws2019/ipi/cpp_headers/NorImp.cc b/ws2019/ipi/cpp_headers/NorImp.cc new file mode 100644 index 0000000..719a149 --- /dev/null +++ b/ws2019/ipi/cpp_headers/NorImp.cc @@ -0,0 +1,49 @@ +Nor::Nor() +{ + a=b=c=0; // nix angschlossen + actionFlag=false; +} + +Nor::~Nor() {} + +void Nor::ChangeInput (State s, int pin) +{ + // Sorge dafuer, dass Gatter neu berechnet wird, wenn + // alle Zustaende der Eingaenge (Draehte) festliegen + if (!actionFlag) + { + Sim.StoreCircuitEvent(*this); + actionFlag=true; + } +} + +void Nor::Action () +{ + // Lese Eingangssignale + State A = a->GetState(); + State B = b->GetState(); + State Output=unknown; + + // Wertetabelle + if (A==low && B==low) Output=high; + if (A==high|| B==high) Output=low; + + // Setze Draht + if (c!=0) c->ChangeState(Sim.GetTime()+3,Output); + + // erlaube neue Auswertung + actionFlag=false; +} + +void Nor::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) a = &w; + if (pin==1) b = &w; +} + +void Nor::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + c = &w; +} diff --git a/ws2019/ipi/cpp_headers/Or.hh b/ws2019/ipi/cpp_headers/Or.hh new file mode 100644 index 0000000..a075985 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Or.hh @@ -0,0 +1,27 @@ +class Or : public Circuit { +public: + Or (); + // Konstruktor + + ~Or (); + // default destructor ist OK + + virtual void ChangeInput (State s, int pin); + // Eingang wechselt zur aktuellen Zeit den Zustand + + virtual void Action (); + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + + virtual void ConnectInput (Wire& w, int pin); + // verdrahte Eingang + + virtual void ConnectOutput (Wire& w, int pin); + // verdrahte Ausgang + +private: + Wire* a; // Eingang 1 + Wire* b; // Eingang 2 + Wire* c; // Ausgang + bool actionFlag; // merke ob bereits aktiviert +} ; diff --git a/ws2019/ipi/cpp_headers/OrImp.cc b/ws2019/ipi/cpp_headers/OrImp.cc new file mode 100644 index 0000000..20c61af --- /dev/null +++ b/ws2019/ipi/cpp_headers/OrImp.cc @@ -0,0 +1,49 @@ +Or::Or() +{ + a=b=c=0; // nix angschlossen + actionFlag=false; +} + +Or::~Or() {} + +void Or::ChangeInput (State s, int pin) +{ + // Sorge dafuer, dass Gatter neu berechnet wird, wenn + // alle Zustaende der Eingaenge (Draehte) festliegen + if (!actionFlag) + { + Sim.StoreCircuitEvent(*this); + actionFlag=true; + } +} + +void Or::Action () +{ + // Lese Eingangssignale + State A = a->GetState(); + State B = b->GetState(); + State Output=unknown; + + // Wertetabelle + if (A==low && B==low) Output=low; + if (A==high|| B==high) Output=high; + + // Setze Draht + if (c!=0) c->ChangeState(Sim.GetTime()+3,Output); + + // erlaube neue Auswertung + actionFlag=false; +} + +void Or::ConnectInput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + if (pin==0) a = &w; + if (pin==1) b = &w; +} + +void Or::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + c = &w; +} diff --git a/ws2019/ipi/cpp_headers/Polynomial.hh b/ws2019/ipi/cpp_headers/Polynomial.hh new file mode 100644 index 0000000..88d7935 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Polynomial.hh @@ -0,0 +1,28 @@ +class Polynomial : + public SimpleFloatArray { +public: + // konstruiere Polynom vom Grad n + Polynomial (int n); + + // Default-Destruktor ist ok + // Default-Copy-Konstruktor ist ok + // Default-Zuweisung ist ok + + // Grad des Polynoms + int degree (); + + // Auswertung + float eval (float x); + + // Addition von Polynomen + Polynomial operator+ (Polynomial q); + + // Multiplikation von Polynomen + Polynomial operator* (Polynomial q); + + // Gleichheit + bool operator== (Polynomial q); + + // drucke Polynom + void print (); +} ; diff --git a/ws2019/ipi/cpp_headers/PolynomialEqual.cc b/ws2019/ipi/cpp_headers/PolynomialEqual.cc new file mode 100644 index 0000000..3ec2c9c --- /dev/null +++ b/ws2019/ipi/cpp_headers/PolynomialEqual.cc @@ -0,0 +1,19 @@ +bool Polynomial::operator== (Polynomial q) +{ + if (q.degree()>degree()) + { + for (int i=0; i<=degree(); i=i+1) + if ((*this)[i]!=q[i]) return false; + for (int i=degree()+1; i<=q.degree(); i=i+1) + if (q[i]!=0.0) return false; + } + else + { + for (int i=0; i<=q.degree(); i=i+1) + if ((*this)[i]!=q[i]) return false; + for (int i=q.degree()+1; i<=degree(); i=i+1) + if ((*this)[i]!=0.0) return false; + } + + return true; +} diff --git a/ws2019/ipi/cpp_headers/PolynomialEval.cc b/ws2019/ipi/cpp_headers/PolynomialEval.cc new file mode 100644 index 0000000..73b35e3 --- /dev/null +++ b/ws2019/ipi/cpp_headers/PolynomialEval.cc @@ -0,0 +1,10 @@ +// Auswertung +float Polynomial::eval (float x) +{ + float sum=0.0; + + // Hornerschema + for (int i=maxIndex(); i>=0; i=i-1) + sum = sum*x + operator[](i); + return sum; +} diff --git a/ws2019/ipi/cpp_headers/PolynomialImp.cc b/ws2019/ipi/cpp_headers/PolynomialImp.cc new file mode 100644 index 0000000..d3abc0f --- /dev/null +++ b/ws2019/ipi/cpp_headers/PolynomialImp.cc @@ -0,0 +1,51 @@ +// Grad auswerten +int Polynomial::degree () +{ + return maxIndex(); +} + +// Addition von Polynomen +Polynomial Polynomial::operator+ (Polynomial q) +{ + int nr=degree(); // mein grad + + if (q.degree()>nr) nr=q.degree(); + + Polynomial r(nr); // Ergebnispolynom + + for (int i=0; i<=nr; i=i+1) + { + if (i<=degree()) + r[i] = r[i]+(*this)[i]; // add me to r + if (i<=q.degree()) + r[i] = r[i]+q[i]; // add q to r + } + + return r; +} + +// Multiplikation von Polynomen +Polynomial Polynomial::operator* (Polynomial q) +{ + Polynomial r(degree()+q.degree()); // Ergebnispolynom + + for (int i=0; i<=degree(); i=i+1) + for (int j=0; j<=q.degree(); j=j+1) + r[i+j] = r[i+j] + (*this)[i]*q[j]; + + return r; +} + +// Drucken +void Polynomial::print () +{ + if (degree()<0) + std::cout << 0; + else + std::cout << (*this)[0]; + + for (int i=1; i<=maxIndex(); i=i+1) + std::cout << "+" << (*this)[i] << "*x^" << i; + + std::cout << std::endl; +} diff --git a/ws2019/ipi/cpp_headers/PolynomialKons.cc b/ws2019/ipi/cpp_headers/PolynomialKons.cc new file mode 100644 index 0000000..0e1c8b1 --- /dev/null +++ b/ws2019/ipi/cpp_headers/PolynomialKons.cc @@ -0,0 +1,2 @@ +Polynomial::Polynomial (int n) + : SimpleFloatArray(n+1,0.0) {} diff --git a/ws2019/ipi/cpp_headers/Programm.cc b/ws2019/ipi/cpp_headers/Programm.cc new file mode 100644 index 0000000..c2b3a74 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Programm.cc @@ -0,0 +1,124 @@ +// Konstruktor fuer leeres Programm +Programm::Programm () +{ + zeilen = 0; // noch keine gueltige Zeile + fertig = false; +} + +// Fuege eine Zeile in die Zustandsuebrgangstabelle hinzu +void Programm::zeile (int q_ein, char s_ein, char s_aus, R richt, int q_aus) +{ + if (fertig) { + print("Programm war schon abgeschlossen!"); + return; + } + Qaktuell[zeilen] = q_ein; + eingabe[zeilen] = s_ein; + ausgabe[zeilen] = s_aus; + richtung[zeilen] = richt; + Qfolge[zeilen] = q_aus; + zeilen = zeilen+1; +} + +// Definiere letzte Zeile in der Zustandsuebergangstabelle +void Programm::zeile (int endzustand) +{ + if (fertig) { + print("Programm war schon abgeschlossen!"); + return; + } + Qaktuell[zeilen] = endzustand; + zeilen = zeilen+1; + fertig = true; + print("Programm mit ",zeilen," Zeilen definiert",0); + print("Anfangszustand ",Anfangszustand(),0); + print("Endzustand ",Endzustand(),0); +} + +// Ermittle zu schreibendes Zeichen +char Programm::Ausgabe (int q, char symbol) +{ + // wurde Zeile als letztes benutzt ? + if ( letztesQ==q && letzteEingabe==symbol ) + return ausgabe[letzteZeile]; + // suche Zeile im Programm + if (FindeZeile(q,symbol)) + return ausgabe[letzteZeile]; + // Fehler: es gibt keine solche Zeile + print(q," , ",symbol,0); + print(" nicht definiert!"); + return 0; +} + +// Ermittle Richtung +Programm::R Programm::Richtung (int q, char symbol) +{ + // wurde Zeile als letztes benutzt ? + if ( letztesQ==q && letzteEingabe==symbol ) + return richtung[letzteZeile]; + // suche Zeile im Programm + if (FindeZeile(q,symbol)) + return richtung[letzteZeile]; + // Fehler: es gibt keine solche Zeile + print(q," , ",symbol,0); + print(" nicht definiert!"); + return links; +} + +// Ermittle Folgezustand +int Programm::Folgezustand (int q, char symbol) +{ + // wurde Zeile als letztes benutzt ? + if ( letztesQ==q && letzteEingabe==symbol ) + return Qfolge[letzteZeile]; + // suche Zeile im Programm + if (FindeZeile(q,symbol)) + return Qfolge[letzteZeile]; + // Fehler: es gibt keine solche Zeile + print(q," , ",symbol,0); + print(" nicht definiert!"); + return -1; +} + +// Gebe Anfangszustand zurueck +int Programm::Anfangszustand () +{ + return Qaktuell[0]; +} + +// Gebe Endzustand zurueck +int Programm::Endzustand () +{ + return Qaktuell[zeilen-1]; +} + +// Finde Zeile in der Zustandsuebergangstabelle zu gegebenem +// Zustand und Symbol. Merke Eingabe und Zeilennummer damit +// bei wiederholtem Zugriff nicht gesucht werden muss. +bool Programm::FindeZeile (int q, char symbol) +{ + for (int i=0; i +class Ptr { + struct RefCntObj { + int count; + T* obj; + RefCntObj (T* q) { count = 1; obj = q; } + }; + RefCntObj* p; + + void report () { + std::cout << "refcnt = " << p->count << std::endl; + } + void increment () { + p->count = p->count + 1; + report(); + } + void decrement () { + p->count = p->count - 1; + report(); + if (p->count==0) { + delete p->obj; // Geht nicht fuer Felder! + delete p; + } + } + +public: + Ptr () { p=0; } + + Ptr (T* q) { + p = new RefCntObj(q); + report(); + } + + Ptr (const Ptr& y) { + p = y.p; + if (p!=0) increment(); + } + + ~Ptr () { + if (p!=0) decrement(); + } + + Ptr& operator= (const Ptr& y) { + if (p!=y.p) { + if (p!=0) decrement(); + p = y.p; + if (p!=0) increment(); + } + return *this; + } + + T& operator* () { return *(p->obj); } + + T* operator-> () { return p->obj; } +}; diff --git a/ws2019/ipi/cpp_headers/PtrTest.cc b/ws2019/ipi/cpp_headers/PtrTest.cc new file mode 100644 index 0000000..582e0b6 --- /dev/null +++ b/ws2019/ipi/cpp_headers/PtrTest.cc @@ -0,0 +1,19 @@ +#include + +#include"Ptr.hh" + +int g (Ptr p) { + return *p; +} + +int main () +{ + Ptr q = new int(17); + std::cout << *q << std::endl; + int x = g(q); + std::cout << x << std::endl; + Ptr z = new int(22); + q = z; + std::cout << *q << std::endl; + // nun wird alles automatisch geloescht ! +} diff --git a/ws2019/ipi/cpp_headers/Queue.hh b/ws2019/ipi/cpp_headers/Queue.hh new file mode 100644 index 0000000..b882227 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Queue.hh @@ -0,0 +1,20 @@ +template +class Queue : public DLList { +public : + // Default-Konstruktoren + Zuweisung OK + bool empty () { + return DLList::empty(); + } + T front () { + return *DLList::begin(); + } + T back () { + return *DLList::rbegin(); + } + void push (T t) { + this->insert(DLList::end(),t); + } + void pop () { + this->erase(DLList::begin()); + } +} ; diff --git a/ws2019/ipi/cpp_headers/Quicksort.cc b/ws2019/ipi/cpp_headers/Quicksort.cc new file mode 100644 index 0000000..667d0f3 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Quicksort.cc @@ -0,0 +1,30 @@ +template +int qs_partition (C& a, int l, int r, int q) { + std::swap(a[q],a[r]); + q=r; // Pivot ist jetzt ganz rechts + int i=l-1, j=r; + + while (i=a[q]) j=j-1; + if (i +void qs_rec (C& a, int l, int r) { + if (l +void quicksort (C& a) { + qs_rec(a,0,a.size()-1); +} diff --git a/ws2019/ipi/cpp_headers/Rational.cc b/ws2019/ipi/cpp_headers/Rational.cc new file mode 100644 index 0000000..48145a8 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Rational.cc @@ -0,0 +1,59 @@ +int Rational::numerator () { + return n; +} + +int Rational::denominator () { + return d; +} + +void Rational::print () { + ::print(n,"/",d,0); +} + +// ggT zum kuerzen +int Rational::ggT (int a, int b) { + return (b==0) ? a : ggT(b,a%b); +} + +// Konstruktoren +Rational::Rational (int num, int denom) +{ + int t = ggT(num,denom); + if (t!=0) + { + n=num/t; + d=denom/t; + } + else + { + n = num; + d = denom; + } +} + +Rational::Rational (int num) { + n=num; + d=1; +} + +Rational::Rational () { + n=0; + d=1; +} + +// Operatoren +Rational Rational::operator+ (Rational q) { + return Rational(n*q.d+q.n*d,d*q.d); +} + +Rational Rational::operator- (Rational q) { + return Rational(n*q.d-q.n*d, d*q.d); +} + +Rational Rational::operator* (Rational q) { + return Rational(n*q.n, d*q.d); +} + +Rational Rational::operator/ (Rational q) { + return Rational(n*q.d,d*q.n); +} diff --git a/ws2019/ipi/cpp_headers/Rational.hh b/ws2019/ipi/cpp_headers/Rational.hh new file mode 100644 index 0000000..35d4c77 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Rational.hh @@ -0,0 +1,23 @@ +class Rational { +private: + int n,d; + int ggT (int a, int b); +public: + // (lesender) Zugriff auf Zaehler und Nenner + int numerator (); + int denominator (); + + // Konstruktoren + Rational (int num, int denom); // rational + Rational (int num); // ganz + Rational (); // Null + + // Ausgabe + void print (); + + // Operatoren + Rational operator+ (Rational q); + Rational operator- (Rational q); + Rational operator* (Rational q); + Rational operator/ (Rational q); +} ; diff --git a/ws2019/ipi/cpp_headers/Rational2.cc b/ws2019/ipi/cpp_headers/Rational2.cc new file mode 100644 index 0000000..0b18fd8 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Rational2.cc @@ -0,0 +1,72 @@ +#include "fcpp.hh" + +struct Rational { + int zaehler; + int nenner; +} ; + +// Abstraktion: Konstruktor und Selektoren + +Rational erzeuge_rat (int z, int n) +{ + Rational t; + t.zaehler = z; + t.nenner = n; + return t; +} + +int zaehler (Rational q) +{ + return q.zaehler; +} + +int nenner (Rational q) +{ + return q.nenner; +} + +// Arithmetische Operationen + +Rational add_rat (Rational p, Rational q) +{ + return erzeuge_rat( + zaehler(p)*nenner(q)+zaehler(q)*nenner(p), + nenner(p)*nenner(q)); +} + +Rational sub_rat (Rational p, Rational q) +{ + return erzeuge_rat( + zaehler(p)*nenner(q)-zaehler(q)*nenner(p), + nenner(p)*nenner(q)); +} + +Rational mul_rat (Rational p, Rational q) +{ + return erzeuge_rat(zaehler(p)*zaehler(q), + nenner(p)*nenner(q)); +} + +Rational div_rat (Rational p, Rational q) +{ + return erzeuge_rat(zaehler(p)*nenner(q), + nenner(p)*zaehler(q)); +} + +void drucke_rat (Rational p) +{ + print(zaehler(p),"/",nenner(p),0); +} + +int main () +{ + Rational p = erzeuge_rat(3,4); + Rational q = erzeuge_rat(5,3); + drucke_rat(p); drucke_rat(q); + + // p*q+p-p*p + Rational r = sub_rat(add_rat(mul_rat(p,q), p), + mul_rat(p,p)); + drucke_rat(r); + return 0; +} diff --git a/ws2019/ipi/cpp_headers/RationalOutput.cc b/ws2019/ipi/cpp_headers/RationalOutput.cc new file mode 100644 index 0000000..c2b2999 --- /dev/null +++ b/ws2019/ipi/cpp_headers/RationalOutput.cc @@ -0,0 +1,6 @@ +std::ostream& +operator<< (std::ostream& s, Rational q) +{ + s << q.numerator() << "/" << q.denominator(); + return s; +} diff --git a/ws2019/ipi/cpp_headers/Selectionsort.cc b/ws2019/ipi/cpp_headers/Selectionsort.cc new file mode 100644 index 0000000..7cf9c5f --- /dev/null +++ b/ws2019/ipi/cpp_headers/Selectionsort.cc @@ -0,0 +1,11 @@ +template +void selectionsort (C& a) +{ + for (int i=0; i +class Set : private DLList { +public : + // Default-Konstruktoren + Zuweisung OK + + typedef typename DLList::Iterator Iterator; + Iterator begin(); + Iterator end(); + + bool empty (); + bool member (T t); + void insert (T t); + void remove (T t); + // union, intersection, ... ? +} ; diff --git a/ws2019/ipi/cpp_headers/SetImp.cc b/ws2019/ipi/cpp_headers/SetImp.cc new file mode 100644 index 0000000..9e4261c --- /dev/null +++ b/ws2019/ipi/cpp_headers/SetImp.cc @@ -0,0 +1,34 @@ +template +typename Set::Iterator Set::begin() { + return DLList::begin(); +} + +template +typename Set::Iterator Set::end() { + return DLList::end(); +} + +template +bool Set::empty () { + return DLList::empty(); +} + +template +inline bool Set::member (T t) { + return find(t)!=DLList::end(); +} + +template +inline void Set::insert (T t) +{ + if (!member(t)) + DLList::insert(DLList::begin(),t); +} + +template +inline void Set::remove (T t) +{ + typename DLList::Iterator i = find(t); + if (i!=DLList::end()) + erase(i); +} diff --git a/ws2019/ipi/cpp_headers/SimpleArray.hh b/ws2019/ipi/cpp_headers/SimpleArray.hh new file mode 100644 index 0000000..5779254 --- /dev/null +++ b/ws2019/ipi/cpp_headers/SimpleArray.hh @@ -0,0 +1,19 @@ +template +class SimpleArray { +public: + SimpleArray (int s, T f); + SimpleArray (const SimpleArray&); + SimpleArray& operator= + (const SimpleArray&); + ~SimpleArray(); + + T& operator[](int i); + int numIndices (); + int minIndex (); + int maxIndex (); + bool isMember (int i); + +private: + int n; // Anzahl Elemente + T *p; // Zeiger auf built-in array +} ; diff --git a/ws2019/ipi/cpp_headers/SimpleArrayCS.hh b/ws2019/ipi/cpp_headers/SimpleArrayCS.hh new file mode 100644 index 0000000..48db8e5 --- /dev/null +++ b/ws2019/ipi/cpp_headers/SimpleArrayCS.hh @@ -0,0 +1,27 @@ +template +class SimpleArrayCS { +public: + SimpleArrayCS (T f); + // Erzeuge ein neues Feld mit m Elementen, I=[0,m-1] + + // Copy-Konstruktor, Zuweisung, Destruktor: Default ist OK! + + T& operator[](int i); + // Indizierter Zugriff auf Feldelemente + // keine Ueberpruefung ob Index erlaubt + + int numIndices (); + // Anzahl der Indizes in der Indexmenge + + int minIndex (); + // kleinster Index + + int maxIndex (); + // größter Index + + bool isMember (int i); + // Ist der Index in der Indexmenge? + +private: + T p[m]; // built-in array fester Groesse +} ; diff --git a/ws2019/ipi/cpp_headers/SimpleArrayCSImp.cc b/ws2019/ipi/cpp_headers/SimpleArrayCSImp.cc new file mode 100644 index 0000000..c3da84f --- /dev/null +++ b/ws2019/ipi/cpp_headers/SimpleArrayCSImp.cc @@ -0,0 +1,35 @@ +template +inline SimpleArrayCS::SimpleArrayCS (T v) +{ + for (int i=0; i +inline T& SimpleArrayCS::operator[] (int i) +{ + return p[i]; +} + +template +inline int SimpleArrayCS::numIndices () { return m; } + +template +inline int SimpleArrayCS::minIndex () { return 0; } + +template +inline int SimpleArrayCS::maxIndex () { return m-1; } + +template +inline bool SimpleArrayCS::isMember (int i) +{ + if (i>=0 && i +std::ostream& operator<< (std::ostream& s, SimpleArrayCS& a) +{ + for (int i=a.minIndex(); i<=a.maxIndex(); i=i+1) + s << i << " " << a[i] << std::endl; + return s; +} diff --git a/ws2019/ipi/cpp_headers/SimpleArrayImp.cc b/ws2019/ipi/cpp_headers/SimpleArrayImp.cc new file mode 100644 index 0000000..1749696 --- /dev/null +++ b/ws2019/ipi/cpp_headers/SimpleArrayImp.cc @@ -0,0 +1,81 @@ +// Destruktor +template +SimpleArray::~SimpleArray () { + delete[] p; +} + +// Konstruktor +template +SimpleArray::SimpleArray (int s, T v) +{ + n = s; + p = new T[n]; + for (int i=0; i +SimpleArray::SimpleArray (const + SimpleArray& a) { + n = a.n; + p = new T[n]; + for (int i=0; i +SimpleArray& SimpleArray::operator= + (const SimpleArray& a) +{ + if (&a!=this) { + if (n!=a.n) { + delete[] p; + n = a.n; + p = new T[n]; + } + for (int i=0; i +inline T& SimpleArray::operator[] (int i) +{ + return p[i]; +} + +template +inline int SimpleArray::numIndices () +{ + return n; +} + +template +inline int SimpleArray::minIndex () +{ + return 0; +} + +template +inline int SimpleArray::maxIndex () +{ + return n-1; +} + +template +inline bool SimpleArray::isMember (int i) +{ + return (i>=0 && i +std::ostream& operator<< (std::ostream& s, + SimpleArray& a) +{ + s << "#( "; + for (int i=a.minIndex(); i<=a.maxIndex(); i=i+1) + s << a[i] << " "; + s << ")" << std::endl; + return s; +} diff --git a/ws2019/ipi/cpp_headers/SimpleFloatArray.hh b/ws2019/ipi/cpp_headers/SimpleFloatArray.hh new file mode 100644 index 0000000..1e9dc12 --- /dev/null +++ b/ws2019/ipi/cpp_headers/SimpleFloatArray.hh @@ -0,0 +1,34 @@ +class SimpleFloatArray { +public: + // Neues Feld mit s Elementen, I=[0,s-1] + SimpleFloatArray (int s, float f); + + // Copy-Konstruktor + SimpleFloatArray (const SimpleFloatArray&); + + // Zuweisung von Feldern + SimpleFloatArray& operator= (const SimpleFloatArray&); + + // Destruktor: Gebe Speicher frei + ~SimpleFloatArray(); + + // Indizierter Zugriff auf Feldelemente + // keine Ueberpruefung ob Index erlaubt + float& operator[](int i); + + // Anzahl der Indizes in der Indexmenge + int numIndices (); + + // kleinster Index + int minIndex (); + + // größter Index + int maxIndex (); + + // Ist der Index in der Indexmenge? + bool isMember (int i); + +private: + int n; // Anzahl Elemente + float *p; // Zeiger auf built-in array +} ; diff --git a/ws2019/ipi/cpp_headers/SimpleFloatArrayAssign.cc b/ws2019/ipi/cpp_headers/SimpleFloatArrayAssign.cc new file mode 100644 index 0000000..0cff6aa --- /dev/null +++ b/ws2019/ipi/cpp_headers/SimpleFloatArrayAssign.cc @@ -0,0 +1,19 @@ +SimpleFloatArray& SimpleFloatArray::operator= +(const SimpleFloatArray& a) +{ + // nur bei verschiedenen Objekten ist was tun + if (&a!=this) + { + if (n!=a.n) { + // allokiere fuer this ein + // Feld der Groesse a.n + delete[] p; // altes Feld loeschen + n = a.n; + p = new float[n]; // keine Fehlerbeh. + } + for (int i=0; i=0 && i pq; // Fuer (B)-Ereignisse + Queue q; // Fuer (D)-Ereignisse +} ; + +// Globale Variable vom Typ Simulator (Singleton). +// Wird von allen Bausteinen und Draehten benutzt! +Simulator Sim; diff --git a/ws2019/ipi/cpp_headers/SimulatorImp.cc b/ws2019/ipi/cpp_headers/SimulatorImp.cc new file mode 100644 index 0000000..bc7a53f --- /dev/null +++ b/ws2019/ipi/cpp_headers/SimulatorImp.cc @@ -0,0 +1,54 @@ +// Methoden fuer die geschachtelte Klasse +Simulator::WireEvent::WireEvent () { w=0; t=0; s=unknown; } + +Simulator::WireEvent::WireEvent (Wire& W, int T, State S) {w=&W; t=T; s=S;} + +bool Simulator::WireEvent::operator< (WireEvent we) +{ + if (t(w)(we.w))) return true; + return false; +} + +// Konstruktor +Simulator::Simulator (){time = 0;} + +int Simulator::GetTime (){return time;} + +void Simulator::StoreWireEvent (Wire& w, int t, State s) +{ + pq.push(WireEvent(w,t,s)); +} + +void Simulator::StoreCircuitEvent (Circuit& c) +{ + q.push(&c); +} + +void Simulator::Simulate (int end) +{ + WireEvent we; + + while (time<=end) + { + // Alle Draehte fuer die aktuelle Zeit + while (!pq.empty()) + { + we = pq.top(); // kleinster Eintrag + if (we.t>time) break; // alle Zustaende fuer Zeitschritt OK + pq.pop(); // entferne Eintrag + (we.w)->Action(we.s); // neuer Zustand + } + + // Berechne Bausteine zur aktuellen Zeit neu + while (!q.empty()) + { + (q.front())->Action(); + q.pop(); + } + + // Zeitschritt fertig + time = time+1; + } +} + diff --git a/ws2019/ipi/cpp_headers/Stack.hh b/ws2019/ipi/cpp_headers/Stack.hh new file mode 100644 index 0000000..93d3575 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Stack.hh @@ -0,0 +1,12 @@ +template +class Stack : private DLList { +public : + // Default-Konstruktoren + Zuweisung OK + + bool empty () {return DLList::empty();} + void push (T t) { + this->insert(DLList::begin(),t); + } + T top () {return *DLList::begin();} + void pop () {this->erase(DLList::begin());} +} ; diff --git a/ws2019/ipi/cpp_headers/TM.cc b/ws2019/ipi/cpp_headers/TM.cc new file mode 100644 index 0000000..d6a2fb2 --- /dev/null +++ b/ws2019/ipi/cpp_headers/TM.cc @@ -0,0 +1,28 @@ +// Konstruiere die TM mit Programm und Band +TM::TM (Programm& p, Band& b) : prog(p), band(b) +{ + q=p.Anfangszustand(); +} + +// einen Schritt machen +void TM::Schritt () +{ + // lese Bandsymbol + char s = band.lese(); + + // schreibe Band + if (prog.Richtung(q,s)==Programm::links) + band.schreibe_links(prog.Ausgabe(q,s)); + else + band.schreibe_rechts(prog.Ausgabe(q,s)); + + // bestimme Folgezustand + q = prog.Folgezustand(q,s); +} + +// Ist Endzustand erreicht? +bool TM::Endzustand () +{ + if (q==prog.Endzustand()) return true; else return false; +} + diff --git a/ws2019/ipi/cpp_headers/TM.hh b/ws2019/ipi/cpp_headers/TM.hh new file mode 100644 index 0000000..424b86b --- /dev/null +++ b/ws2019/ipi/cpp_headers/TM.hh @@ -0,0 +1,19 @@ +// Klasse, die eine Turingmaschine realisiert +class TM { +public: + // Konstruiere Maschine mit Programm + // und Band + TM (Programm& p, Band& b); + + // Mache einen Schritt + void Schritt (); + + // Liefere true falls sich Maschine im + // Endzustand befindet + bool Endzustand (); + +private: + Programm& prog; // Merke Programm + Band& band; // Merke Band + int q; // Merke akt. Zustand +} ; diff --git a/ws2019/ipi/cpp_headers/Terminal.hh b/ws2019/ipi/cpp_headers/Terminal.hh new file mode 100644 index 0000000..7a435a9 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Terminal.hh @@ -0,0 +1,25 @@ +class Terminal : public Circuit { +public: + Terminal (State s); + // Konstruktor + + ~Terminal (); + // default destructor ist OK + + virtual void ChangeInput (State s, int pin); + // Eingang wechselt zur aktuellen Zeit den Zustand + + virtual void Action (); + // berechne Gatter neu und benachrichtige Draht + // am Ausgang + + virtual void ConnectInput (Wire& w, int pin); + // verdrahte Eingang + + virtual void ConnectOutput (Wire& w, int pin); + // verdrahte Ausgang + +private: + State q; // Ausgabewert + Wire* a; // Ausgang +} ; diff --git a/ws2019/ipi/cpp_headers/TerminalImp.cc b/ws2019/ipi/cpp_headers/TerminalImp.cc new file mode 100644 index 0000000..e89b266 --- /dev/null +++ b/ws2019/ipi/cpp_headers/TerminalImp.cc @@ -0,0 +1,24 @@ +Terminal::Terminal (State s) +{ + q = s; // Wert des Terminals + a=0; // nix angschlossen + Sim.StoreCircuitEvent(*this); +} + +Terminal::~Terminal() {} + +void Terminal::ChangeInput (State s, int pin) {} + +void Terminal::Action () +{ + // Stosse Draht an + a->ChangeState(Sim.GetTime()+1,q); +} + +void Terminal::ConnectInput (Wire& w, int pin) {} + +void Terminal::ConnectOutput (Wire& w, int pin) +{ + // Wird von Connect-Funktion des Drahtes aufgerufen + a = &w; +} diff --git a/ws2019/ipi/cpp_headers/Turingmaschine.cc b/ws2019/ipi/cpp_headers/Turingmaschine.cc new file mode 100644 index 0000000..a5b6234 --- /dev/null +++ b/ws2019/ipi/cpp_headers/Turingmaschine.cc @@ -0,0 +1,43 @@ +#include "fcpp.hh" // fuer print + +#include"Band.hh" // Inkludiere Quelldateien +#include"Band.cc" +#include"Programm.hh" +#include"Programm.cc" +#include"TM.hh" +#include"TM.cc" + +int main (int argc, char *argv[]) +{ + // Initialisiere ein Band + Band b("1111",'0'); + b.drucke(); + + // Initialisiere ein Programm + Programm p; + p.zeile(1,'1','X',Programm::rechts,2); + p.zeile(2,'1','1',Programm::rechts,2); + p.zeile(2,'0','Y',Programm::links,3); + p.zeile(3,'1','1',Programm::links,3); + p.zeile(3,'X','1',Programm::rechts,4); + p.zeile(4,'Y','1',Programm::rechts,8); + p.zeile(4,'1','X',Programm::rechts,5); + p.zeile(5,'1','1',Programm::rechts,5); + p.zeile(5,'Y','Y',Programm::rechts,6); + p.zeile(6,'1','1',Programm::rechts,6); + p.zeile(6,'0','1',Programm::links,7); + p.zeile(7,'1','1',Programm::links,7); + p.zeile(7,'Y','Y',Programm::links,3); + p.zeile(8); + + // Baue eine Turingmaschine + TM tm(p,b); + + // Simuliere Turingmaschine + while (!tm.Endzustand()) { // Solange nicht Endzustand + tm.Schritt() ; // mache einen Schritt + b.drucke(); // und drucke Band + } + + return 0; // fertig. +} diff --git a/ws2019/ipi/cpp_headers/UseBoth.cc b/ws2019/ipi/cpp_headers/UseBoth.cc new file mode 100644 index 0000000..db1e3c7 --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseBoth.cc @@ -0,0 +1,26 @@ +#include +#include + +#include"Array.hh" +#include"DLL.hh" +#include"Zufall.cc" + +int main () { + Zufall z(87124); + Array a(5); + DLList l; + + // Erzeuge Array und Liste mit 5 Zufallszahlen + for (int i=0; i<5; i=i+1) a[i] = z.ziehe_zahl(); + for (int i=0; i<5; i=i+1) + l.insert(l.end(), z.ziehe_zahl()); + + // Benutzung + for (Array::Iterator i=a.begin(); + i!=a.end(); i++) + std::cout << *i << std::endl; + std::cout << std::endl; + for (DLList::Iterator i=l.begin(); + i!=l.end(); i++) + std::cout << *i << std::endl; +} diff --git a/ws2019/ipi/cpp_headers/UseBubblesort.cc b/ws2019/ipi/cpp_headers/UseBubblesort.cc new file mode 100644 index 0000000..a534f3a --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseBubblesort.cc @@ -0,0 +1,65 @@ +#include + +// SimpleFloatArray mit virtuellem operator[] +#include "SimpleFloatArrayV.hh" +#include "SimpleFloatArrayImp.cc" +#include "SimpleFloatArrayIndex.cc" +#include "SimpleFloatArrayCopyCons.cc" +#include "SimpleFloatArrayAssign.cc" + +// templatisierte Variante mit variabler Groesse +#include "SimpleArray.hh" +#include "SimpleArrayImp.cc" + +// templatisierte Variante mit Compile-Zeit Groesse +#include "SimpleArrayCS.hh" +#include "SimpleArrayCSImp.cc" + +// dynamisches listenbasiertes Feld +#include "FloatArray.hh" +#include "ListFloatArrayDerived.hh" +#include "ListFloatArrayImp.cc" + +// Zeitmessung +#include "timestamp.cc" + +// generischer bubblesort +#include "bubblesort_.cc" + +// Zufallsgenerator +#include "Zufall.cc" + +const int n = 32000; + +static Zufall z(93576); + +template +void initialisiere (T & a) { + for (int i=0; i a(0.0); + SimpleArray b(n,0.0); + SimpleFloatArray c(n,0.0); + ListFloatArray d; + + initialisiere (a); initialisiere (b); + initialisiere (c); initialisiere (d); + + time_stamp(); + std::cout << "SimpleArrayCS ..."; + bubblesort(a); + std::cout << time_stamp() << " sec" << std::endl; + std::cout << "SimpleArray ..."; + bubblesort(b); + std::cout << time_stamp() << " sec" << std::endl; + std::cout << "SimpleFloatArray ..."; + bubblesort(c); + std::cout << time_stamp() << " sec" << std::endl; + // cout << "ListFloatArray ..."; + // bubblesort(d); + // cout << time_stamp() << " sec" << endl; +} diff --git a/ws2019/ipi/cpp_headers/UseCheckedSimpleFloatArray.cc b/ws2019/ipi/cpp_headers/UseCheckedSimpleFloatArray.cc new file mode 100644 index 0000000..1b56a46 --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseCheckedSimpleFloatArray.cc @@ -0,0 +1,25 @@ +#include +#include + +#include "SimpleFloatArray.hh" +#include "SimpleFloatArrayImp.cc" +#include "SimpleFloatArrayIndex.cc" +#include "SimpleFloatArrayCopyCons.cc" +#include "SimpleFloatArrayAssign.cc" + +#include "CheckedSimpleFloatArray.hh" +#include "CheckedSimpleFloatArrayImp.cc" + +void g (SimpleFloatArray& a) { + std::cout << "beginn in g: " << std::endl; + std::cout << "access: " << a[1] << " " << a[10] << std::endl; + std::cout << "ende in g: " << std::endl; +} + +int main () { + CheckedSimpleFloatArray a(10,0); + g(a); + std::cout << "beginn in main: " << std::endl; + std::cout << "zugriff in main: " << a[10] << std::endl; + std::cout << "ende in main: " << std::endl; +} diff --git a/ws2019/ipi/cpp_headers/UseDLL.cc b/ws2019/ipi/cpp_headers/UseDLL.cc new file mode 100644 index 0000000..1130216 --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseDLL.cc @@ -0,0 +1,36 @@ +#include +#include +#include"DLL.hh" +#include"Zufall.cc" + +int main () +{ + Zufall z(87124); + DLList l1,l2,l3; + + // Erzeuge 3 Listen mit je 5 Zufallszahlen + for (int i=0; i<5; i=i+1) + l1.insert(l1.end(), i); + for (int i=0; i<5; i=i+1) + l2.insert(l2.end(), z.ziehe_zahl()); + for (int i=0; i<5; i=i+1) + l3.insert(l3.end(), z.ziehe_zahl()); + + // Loesche alle geraden in der ersten Liste + DLList::Iterator i,j; + i=l1.begin(); + while (i!=l1.end()) + { + j=i; // merke aktuelles Element + ++i; // gehe zum naechsten + if (*j%2==0) l1.erase(j); + } + + // Liste von Listen ... + DLList > ll; + ll.insert(ll.end(),l1); + ll.insert(ll.end(),l2); + ll.insert(ll.end(),l3); + std::cout << ll << std::endl; + std::cout << "Laenge: " << ll.size() << std::endl; +} diff --git a/ws2019/ipi/cpp_headers/UseFloatArray.cc b/ws2019/ipi/cpp_headers/UseFloatArray.cc new file mode 100644 index 0000000..71557ed --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseFloatArray.cc @@ -0,0 +1,42 @@ +#include + +#include "FloatArray.hh" +#include "DFA.cc" +#include "LFA.cc" + +void polyshow (FloatArray& f) { + for (int i=f.minIndex(); i<=f.maxIndex(); i=i+1) + if (f.isMember(i) && f[i]!=0.0) + std::cout << "+" << f[i] << "*x^" << i; + std::cout << std::endl; +} + +void polymul (FloatArray& a, FloatArray& b, FloatArray& c) { + // Loesche a + for (int i=a.minIndex(); i<=a.maxIndex(); i=i+1) + if (a.isMember(i)) + a[i] = 0.0; + + // a = b*c + for (int i=b.minIndex(); i<=b.maxIndex(); i=i+1) + if (b.isMember(i)) + for (int j=c.minIndex(); j<=c.maxIndex(); j=j+1) + if (c.isMember(j)) + a[i+j] = a[i+j]+b[i]*c[j]; +} + +int main () +{ + // funktioniert mit einer der folgenden Zeilen: + // DynamicFloatArray f,g; + ListFloatArray f,g; + + f[0] = 1.0; f[100] = 1.0; + + polymul(g,f,f); + polymul(f,g,g); + polymul(g,f,f); + polymul(f,g,g); // f=(1+x^100)^16 + + polyshow(f); +} diff --git a/ws2019/ipi/cpp_headers/UseHeap.cc b/ws2019/ipi/cpp_headers/UseHeap.cc new file mode 100644 index 0000000..cd0ac09 --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseHeap.cc @@ -0,0 +1,23 @@ +#include +#include + +#include"Heap.hh" +#include"Zufall.cc" + +int main () +{ + Zufall z(87123); + Heap h; + + for (int i=0; i<10; i=i+1) { + int k = z.ziehe_zahl(); + std::cout << k << std::endl; + h.push(k); + if (i==5) h.pop(); + } + std::cout << std::endl; + while (!h.empty()) { + std::cout << h.top() << std::endl; + h.pop(); + } +} diff --git a/ws2019/ipi/cpp_headers/UseListe.cc b/ws2019/ipi/cpp_headers/UseListe.cc new file mode 100644 index 0000000..87e4f0d --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseListe.cc @@ -0,0 +1,17 @@ +#include +#include"Liste.hh" + +int main () { + List list; + + list.insert(0,17); + list.insert(0,34); + list.insert(0,26); + + for (List::Link* l=list.first(); + l!=0; l=l->next()) + std::cout << l->item << std::endl; + for (List::Link* l=list.first(); + l!=0; l=l->next()) + l->item = 23; +} diff --git a/ws2019/ipi/cpp_headers/UsePolynomial.cc b/ws2019/ipi/cpp_headers/UsePolynomial.cc new file mode 100644 index 0000000..9cd13ce --- /dev/null +++ b/ws2019/ipi/cpp_headers/UsePolynomial.cc @@ -0,0 +1,30 @@ +#include + +// alles zum SimpleFloatArray +#include "SimpleFloatArray.hh" +#include "SimpleFloatArrayImp.cc" +#include "SimpleFloatArrayIndex.cc" +#include "SimpleFloatArrayCopyCons.cc" +#include "SimpleFloatArrayAssign.cc" + +// Das Polynom +#include "Polynomial.hh" +#include "PolynomialImp.cc" +#include "PolynomialKons.cc" +#include "PolynomialEqual.cc" +#include "PolynomialEval.cc" + +int main () +{ + Polynomial p(2),q(10); + + p[0] = 1.0; + p[1] = 1.0; + p.print(); + + q = p*p; + q.print(); + + q = p*p*p; + q.print(); +} diff --git a/ws2019/ipi/cpp_headers/UseQueueSTL.cc b/ws2019/ipi/cpp_headers/UseQueueSTL.cc new file mode 100644 index 0000000..794208a --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseQueueSTL.cc @@ -0,0 +1,13 @@ +#include +#include + +int main () { + std::queue q; + for (int i=1; i<=5; i++) + q.push(i); + + while (!q.empty()) { + std::cout << q.front() << std::endl; + q.pop(); + } +} diff --git a/ws2019/ipi/cpp_headers/UseRational.cc b/ws2019/ipi/cpp_headers/UseRational.cc new file mode 100644 index 0000000..61c11b1 --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseRational.cc @@ -0,0 +1,13 @@ +#include "fcpp.hh" // fuer print +#include "Rational.hh" +#include "Rational.cc" + +int main () { + Rational p(3,4), q(5,3), r; + + p.print(); q.print(); + r = (p+q*p)*p*p; + r.print(); + + return 0; +} diff --git a/ws2019/ipi/cpp_headers/UseRationalOutput.cc b/ws2019/ipi/cpp_headers/UseRationalOutput.cc new file mode 100644 index 0000000..ff72d06 --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseRationalOutput.cc @@ -0,0 +1,13 @@ +#include +#include "fcpp.hh" // fuer print +#include "Rational.hh" +#include "Rational.cc" +#include "RationalOutput.cc" + +int main () { + Rational p(3,4), q(5,3); + + std::cout << p << " " << q << std::endl; + std::cout << (p+q*p)*p*p << std::endl; + return 0; +} diff --git a/ws2019/ipi/cpp_headers/UseSimpleArray.cc b/ws2019/ipi/cpp_headers/UseSimpleArray.cc new file mode 100644 index 0000000..ac0af26 --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseSimpleArray.cc @@ -0,0 +1,19 @@ +#include + +#include "SimpleArray.hh" +#include "SimpleArrayImp.cc" + +int main () +{ + SimpleArray a(10,0.0); // erzeuge + SimpleArray b(25,5); // Felder + + for (int i=a.minIndex(); i<=a.maxIndex(); i++) + a[i] = i; + for (int i=b.minIndex(); i<=b.maxIndex(); i++) + b[i] = i; + + std::cout << a << std::endl << b << std::endl; + + // hier wird der Destruktor gerufen +} diff --git a/ws2019/ipi/cpp_headers/UseSimpleFloatArray.cc b/ws2019/ipi/cpp_headers/UseSimpleFloatArray.cc new file mode 100644 index 0000000..4e5589d --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseSimpleFloatArray.cc @@ -0,0 +1,27 @@ +#include +#include "SimpleFloatArray.hh" +#include "SimpleFloatArrayImp.cc" +#include "SimpleFloatArrayIndex.cc" +#include "SimpleFloatArrayCopyCons.cc" +#include "SimpleFloatArrayAssign.cc" + +void show (SimpleFloatArray f) { + std::cout << "#( "; + for (int i=f.minIndex(); i<=f.maxIndex(); i++) + std::cout << f[i] << " "; + std::cout << ")" << std::endl; +} + +int main () { + SimpleFloatArray a(10,0.0); // erzeuge Felder + SimpleFloatArray b(5,5.0); + + for (int i=a.minIndex(); i<=a.maxIndex(); i++) + a[i] = i; + + show(a); // call by value, ruft Copy-Konstruktor + b = a; // ruft operator= von b + show(b); + + // hier wird der Destruktor beider Objekte gerufen +} diff --git a/ws2019/ipi/cpp_headers/UseSort.cc b/ws2019/ipi/cpp_headers/UseSort.cc new file mode 100644 index 0000000..5cd489e --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseSort.cc @@ -0,0 +1,58 @@ +#include +#include +#include"Bubblesort.cc" +#include"Selectionsort.cc" +#include"Insertionsort.cc" +#include"Mergesort.cc" +#include"Heapsort.cc" +#include"Quicksort.cc" +#include"Zufall.cc" +#include"timestamp.cc" + +void initialize (std::vector& a) { + Zufall z(8267); + for (int i=0; i a(n); + + initialize(a); + time_stamp(); + quicksort(a); + std::cout << "n=" << n << " quicksort t=" + << time_stamp() << std::endl; + + initialize(a); + time_stamp(); + mergesort(a); + std::cout << "n=" << n << " mergesort t=" + << time_stamp() << std::endl; + + initialize(a); + time_stamp(); + heapsort(a); + std::cout << "n=" << n << " heapsort t=" + << time_stamp() << std::endl; + + initialize(a); + time_stamp(); + bubblesort(a); + std::cout << "n=" << n << " bubblesort t=" + << time_stamp() << std::endl; + + initialize(a); + time_stamp(); + insertionsort(a); + std::cout << "n=" << n << " insertionsort t=" + << time_stamp() << std::endl; + + initialize(a); + time_stamp(); + selectionsort(a); + std::cout << "n=" << n << " selectionsort t=" + << time_stamp() << std::endl; +} diff --git a/ws2019/ipi/cpp_headers/UseStack.cc b/ws2019/ipi/cpp_headers/UseStack.cc new file mode 100644 index 0000000..b305e47 --- /dev/null +++ b/ws2019/ipi/cpp_headers/UseStack.cc @@ -0,0 +1,20 @@ +#include +#include + +#include"DLL.hh" +#include"Stack.hh" + +int main () +{ + Stack s1; + for (int i=1; i<=5; i++) + s1.push(i); + + Stack s2(s1); + s2 = s1; + while (!s2.empty()) + { + std::cout << s2.top() << std::endl; + s2.pop(); + } +} diff --git a/ws2019/ipi/cpp_headers/Wire.hh b/ws2019/ipi/cpp_headers/Wire.hh new file mode 100644 index 0000000..f12f4ad --- /dev/null +++ b/ws2019/ipi/cpp_headers/Wire.hh @@ -0,0 +1,30 @@ +// moegliche Zustaende +enum State {low, high, unknown}; + +class Wire { +public: + // Draht im Zustand unknown erzeugen + Wire (); + + // aktuellen Zustand auslesen + State GetState (); + + // (E): Zur Zeit t soll Zustand s werden + void ChangeState (int t, State s); + + // (A): wechsle jetzt in neuen Zustand + void Action (State s); + + // Eingang des Drahtes an Ausgang i des Bausteins c + // anschliessen + void ConnectInput (Circuit& cir, int i); + + // Ausgang des Drahtes an Eingang i des Bausteins c + // anschliessen + void ConnectOutput (Circuit& cir, int i); + +private: + State q; // der Zustand + Circuit* c; // Baustein am Ausgang des Drahtes + int pin; // pin des Bausteins +} ; diff --git a/ws2019/ipi/cpp_headers/WireImp.cc b/ws2019/ipi/cpp_headers/WireImp.cc new file mode 100644 index 0000000..c900072 --- /dev/null +++ b/ws2019/ipi/cpp_headers/WireImp.cc @@ -0,0 +1,39 @@ +Wire::Wire () +{ + // Initialisiere mit unbekanntem Zustand + q = unknown; +} + +inline State Wire::GetState () +{ + return q; +} + + +void Wire::ChangeState (int t, State s) +{ + Sim.StoreWireEvent(*this,t,s); +} + +void Wire::Action (State s) +{ + if (s==q) return; // nix zu tun + q = s; // neuer Zustand + c->ChangeInput(q,pin); // Nachricht an angeschlossen Baustein +} + +void Wire::ConnectInput (Circuit& cir, int i) +{ + // Merke NICHT an wen ich angeschlossen bin + // aber Baustein muss mich kennen. + cir.ConnectOutput(*this,i); +} + +void Wire::ConnectOutput (Circuit& cir, int i) +{ + // Merke Baustein, an den der Ausgang angeschlossen ist + c = ○ + pin = i; + // Rueckverbindung Baustein an Draht + c->ConnectInput(*this,pin); +} diff --git a/ws2019/ipi/cpp_headers/Zufall.cc b/ws2019/ipi/cpp_headers/Zufall.cc new file mode 100644 index 0000000..78dd7ea --- /dev/null +++ b/ws2019/ipi/cpp_headers/Zufall.cc @@ -0,0 +1,24 @@ +class Zufall { +public: + Zufall (unsigned int anfang); + unsigned int ziehe_zahl (); +private: + unsigned int x; +} ; + +Zufall::Zufall (unsigned int anfang) { + x = anfang; +} + +// Implementierung ohne lange Arithmetik +// siehe Numerical Recipes, Kap. 7. +unsigned int Zufall::ziehe_zahl () +{ + // a = 7^5, m = 2^31-1 + unsigned int ia = 16807, im = 2147483647; + unsigned int iq = 127773, ir = 2836; + unsigned int k = x/iq; + x = ia*(x-k*iq)-ir*k; + if (x<0) x = x+im; + return x; +} diff --git a/ws2019/ipi/cpp_headers/ab-tree.cc b/ws2019/ipi/cpp_headers/ab-tree.cc new file mode 100644 index 0000000..e2e40b7 --- /dev/null +++ b/ws2019/ipi/cpp_headers/ab-tree.cc @@ -0,0 +1,179 @@ +#include +#include +#include +#include +using namespace std; + +const int m = 2; // B-tree of order m +const int a = m; // minimal number of keys +const int b = 2*m; // maximal number of keys + +template +struct Node { + // data + vector keys; + vector children; + Node* parent; + // interface + Node (Node* p) {parent = p;} + bool is_leaf() {return children.size()==0;} + Node* root () { return (parent==0) ? this : parent->root(); } + Node* find_node (T item); + int find_pos (T item); + bool equals_item (int pos, T item); +} ; + +// finds first position i such that keys[i]>=item +template +int Node::find_pos (T item) +{ + int i = 0; + while ((i +bool Node::equals_item (int pos, T item) { + return (pos +Node* Node::find_node (T item) { + if (is_leaf()) return this; + int pos = find_pos(item); + if (equals_item(pos, item)) + return this; + else + return children[pos]->find_node(item); +} + +template +VEC subseq (VEC vec, int start, int end) +{ + int size = (vec.size()==0) ? 0 : end-start; + VEC result(size); + for (int i = 0; i +Node* balance (Node* node) +{ + int n = node->keys.size(); + if (n<=b) return 0; + T median = node->keys[a]; + // create a new node + Node* node2 = new Node(node->parent); + node2->keys = subseq(node->keys, a+1, + node->keys.size()); + node2->children = subseq(node->children, a+1, + node->children.size()); + for (int i=0; ichildren.size(); i++) + node2->children[i]->parent = node2; + // handle node + node->keys = subseq(node->keys, 0, a); + node->children = subseq(node->children, 0, a+1); + + Node* parent = node->parent; + if (parent==0) // split the root! + { + Node* root = new Node(0); + root->keys.push_back(median); + root->children.push_back(node); + root->children.push_back(node2); + node->parent = root; + node2->parent = root; + return root; + } + // otherwise: insert in parent + int pos=0; + while (parent->children[pos]!=node) pos++; + parent->keys.insert(parent->keys.begin()+pos, median); + parent->children.insert(parent->children.begin()+pos+1, node2); + // recursive call; + return balance(parent); +} + +template +void show (Node *node) +{ + cout << node << ": "; + if (node->children.size()>0) + { + cout << node->children[0]; + for (int i=0; ikeys.size(); i++) + cout << " |" << node->keys[i] << "| " + << node->children[i+1]; + } + else + for (int i=0; ikeys.size(); i++) + cout << node->keys[i] << " "; + cout << endl; + for (int i=0; ichildren.size(); i++) + show(node->children[i]); +} + +// we could work with a root pointer, but for later use it is +// better to wrap it into a class + +template +class abTree { +public: + abTree () {root = new Node(0);} + void insert (T item); + bool find (T item); + void show () { ::show(root); } +private: + Node *root; +}; + +template +void abTree::insert (T item) { + Node* node = root->find_node(item); + int i=node->find_pos(item); + if (node->equals_item(i,item)) + node->keys[i] = item; + else + { + node->keys.insert(node->keys.begin()+i, item); + Node* new_root = balance(node); + if (new_root) root = new_root; + } +} + +template +bool abTree::find (T item) { + Node* node = root->find_node(item); + int i=node->find_pos(item); + return node->equals_item(i, item); +} + +int main () +{ + abTree tree; + // insertion demo + for (int i=0; i<5; i++) { + tree.insert(i); + tree.show(); + } + // testing insertion and retrieval + int n = 10; + for (int i=0; i set; + set set; // should be faster + int nn = 1000000; + for (int i=0; i void swap (T& a, T&b) { + T t = a; + a = b; + b = t; + } +*/ + +template void bubblesort (C& a) { + for (int i=a.maxIndex(); i>=a.minIndex(); i=i-1) + for (int j=a.minIndex(); j TEMP + mv TEMP $i +done +for i in *.hh; do + echo $i + iconv -f ISO-8859-1 -t UTF-8//TRANSLIT $i > TEMP + mv TEMP $i +done + diff --git a/ws2019/ipi/cpp_headers/enum.cc b/ws2019/ipi/cpp_headers/enum.cc new file mode 100644 index 0000000..ffb4526 --- /dev/null +++ b/ws2019/ipi/cpp_headers/enum.cc @@ -0,0 +1,12 @@ +#include "fcpp.hh" + +enum Zustand { neu, gebraucht, alt, kaputt }; + +void druckeZustand (Zustand x) { + if (x==neu) print("neu"); + if (x==gebraucht) print("gebraucht"); + if (x==alt) print("alt"); + if (x==kaputt) print("kaputt"); +} + +int main () {druckeZustand(alt);} diff --git a/ws2019/ipi/cpp_headers/eratosthenes.cc b/ws2019/ipi/cpp_headers/eratosthenes.cc new file mode 100644 index 0000000..bd8ca9e --- /dev/null +++ b/ws2019/ipi/cpp_headers/eratosthenes.cc @@ -0,0 +1,29 @@ +#include "fcpp.hh" + +int main () +{ + const int n = 500000; + bool prim[n]; + + // Initialisierung + prim[0] = false; + prim[1] = false; + for (int i=2; iende, + produkt, + fakIter(produkt*zaehler,zaehler+1,ende) ); +} +int fakultaet (int n) +{ + return fakIter(1,1,n); +} +int main () +{ + return print(fakultaet(5)); +} diff --git a/ws2019/ipi/cpp_headers/fakultaetiter_mit_ausgabe.cc b/ws2019/ipi/cpp_headers/fakultaetiter_mit_ausgabe.cc new file mode 100644 index 0000000..523878e --- /dev/null +++ b/ws2019/ipi/cpp_headers/fakultaetiter_mit_ausgabe.cc @@ -0,0 +1,11 @@ +#include "fcpp.hh" + +int fakIter (int produkt, int zaehler, int ende) +{ + return cond( zaehler>ende,produkt, + print("Fak:",zaehler,produkt*zaehler, + fakIter(produkt*zaehler,zaehler+1,ende))); +} + +int fakultaet (int n) {return fakIter(1,1,n);} +int main () { return dump(fakultaet(10));} diff --git a/ws2019/ipi/cpp_headers/fakwhile.cc b/ws2019/ipi/cpp_headers/fakwhile.cc new file mode 100644 index 0000000..4cb43cb --- /dev/null +++ b/ws2019/ipi/cpp_headers/fakwhile.cc @@ -0,0 +1,12 @@ +int fak (int n) +{ + int ergebnis=1; + int zaehler=2; + + while (zaehler<=n) + { + ergebnis = zaehler*ergebnis; + zaehler = zaehler+1; + } + return ergebnis; +} diff --git a/ws2019/ipi/cpp_headers/fcpp.hh b/ws2019/ipi/cpp_headers/fcpp.hh new file mode 100644 index 0000000..ebf3a3b --- /dev/null +++ b/ws2019/ipi/cpp_headers/fcpp.hh @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include + +// Die cond Funktion ist ein Makro +#define cond(a,b,c) ( (a) ? (b) : (c) ) + +// Drucke das Argument und gebe es zurueck +template +T print (T x) +{ + std::cout.precision(16); + std::cout << x << std::endl; + return x; +} + +// Drucke Argument 1 und gebe das letzte Argument zurueck +template +T2 print (T1 x1, T2 x2) +{ + std::cout.precision(16); + std::cout << x1 << std::endl; + return x2; +} + +// Drucke Argumente 1-2 und gebe das letzte Argument zurueck +template +T3 print (T1 x1, T2 x2, T3 x3) +{ + std::cout.precision(16); + std::cout << x1 << " " << x2 << std::endl; + return x3; +} + +// Drucke Argumente 1-3 und gebe das letzte Argument zurueck +template +T4 print (T1 x1, T2 x2, T3 x3, T4 x4) +{ + std::cout.precision(16); + std::cout << x1 << " " << x2 << " " << x3 << std::endl; + return x4; +} + +// gebe einfach Null zurueck. Vorsicht: Koennte bei Optimierung dazu +// fuehren, dass das Argument gar nicht berechnet wird. +template +int dump (T x) +{ + return 0; +} + +// Gebe eine int Zahl ein und liefere diese als Ergebnis +int enter_int () +{ + int x; + std::cin >> x; + return x; +} + +// Gebe eine int Zahl ein und liefere diese als Ergebnis +int enter_int (std::string s) +{ + std::cout << s; + int x; + std::cin >> x; + return x; +} + +// Lese Argument i als int-Zahl ein +int readarg_int (int argc, char** argv, int i) +{ + if (argcfirst = 0; // 0 ist keine gueltige Adresse: Liste ist leer + l->count = 0; +} + +// Fuege ein Element nach einem gegebenem ein +void insert_in_list (IntList* list, IntListElem* where, IntListElem* ins) +{ + if (where==0) // fuege am Anfang ein + { + ins->next = list->first; + list->first = ins; + list->count = list->count + 1; + } + else // fuege nach where ein + { + ins->next = where->next; + where->next = ins; + list->count = list->count + 1; + } +} + +// Entferne ein Element nach einem gegebenem +// Liefere das entfernte Element zurueck +IntListElem* remove_from_list (IntList* list, IntListElem* where) +{ + IntListElem* p; // das entfernte Element + + // where==0 dann entferne erstes Element + if (where==0) + { + p = list->first; + if (p!=0) + { + list->first = p->next; + list->count = list->count - 1; + } + return p; + } + + // entferne Element nach where + p = where->next; + if (p!=0) + { + where->next = p->next; + list->count = list->count - 1; + } + return p; +} diff --git a/ws2019/ipi/cpp_headers/intset.cc b/ws2019/ipi/cpp_headers/intset.cc new file mode 100644 index 0000000..c7c2a3e --- /dev/null +++ b/ws2019/ipi/cpp_headers/intset.cc @@ -0,0 +1,68 @@ +// Die Menge wird durch ein IntList realisiert +struct IntSet { + IntList list; +} ; + +// Erzeuge eine leere Menge +IntSet* empty_set () +{ + IntSet* s = new IntSet; + + empty_list(&s->list); + return s; +} + +// pruefe ob x in Menge ist +bool is_in_set (IntSet* s, int x) +{ + for (IntListElem* p=s->list.first; p!=0; p=p->next) + if (p->value==x) return true; + return false; +} + +// Fuege Element in Menge ein +void insert_in_set (IntSet* s, int x) +{ + // pruefe ob Element bereits in Liste + // sonst fuege es ein + if (!is_in_set(s,x)) + { + IntListElem* p = new IntListElem; + p->value = x; + insert_in_list(&s->list,0,p); + } +} + +// Entferne x aus Menge +void remove_from_set (IntSet* s, int x) +{ + // Hat es ueberhaupt Elemente? + if (s->list.first==0) return; + + // Teste erstes Element + if (s->list.first->value==x) + { + IntListElem* p=remove_from_list(&s->list,0); + delete p; + return; + } + + // Suche in Liste, teste immer Nachfolger + // des aktuellen Elementes + for (IntListElem* p=s->list.first; p->next!=0; p=p->next) + if (p->next->value==x) + { + IntListElem* q=remove_from_list(&s->list,p); + delete q; + return; + } +} + +// drucke Liste +void print_set (IntSet* s) +{ + print("("); + for (IntListElem* p=s->list.first; p!=0; p=p->next) + print(" ",p->value,0); + print(")"); +} diff --git a/ws2019/ipi/cpp_headers/iostreamexample.cc b/ws2019/ipi/cpp_headers/iostreamexample.cc new file mode 100644 index 0000000..09b6712 --- /dev/null +++ b/ws2019/ipi/cpp_headers/iostreamexample.cc @@ -0,0 +1,15 @@ +#include + +int main () +{ + int n; + std::cin >> n; // d.h. cin.operator>>(n); + double x; + std::cin >> x; // d.h. cin.operator>>(x); + std::cout << n; // d.h. cout.operator<<(n); + std::cout << " "; + std::cout << x; + std::cout << std::endl; // neue Zeile + std::cout << n << " " << x << std::endl; + return 0; +} diff --git a/ws2019/ipi/cpp_headers/konto1.cc b/ws2019/ipi/cpp_headers/konto1.cc new file mode 100644 index 0000000..0587aa1 --- /dev/null +++ b/ws2019/ipi/cpp_headers/konto1.cc @@ -0,0 +1,27 @@ +#include "fcpp.hh" + +int konto; // die GLOBALE Variable + +void einrichten (int betrag) +{ + konto = betrag; +} + +int kontostand () +{ + return konto; +} + +int abheben (int betrag) +{ + konto = konto-betrag; + return konto; +} + +int main () +{ + einrichten(100); + print(abheben(25)); + print(abheben(25)); + print(abheben(25)); +} diff --git a/ws2019/ipi/cpp_headers/mixed.cc b/ws2019/ipi/cpp_headers/mixed.cc new file mode 100644 index 0000000..8747268 --- /dev/null +++ b/ws2019/ipi/cpp_headers/mixed.cc @@ -0,0 +1,18 @@ +enum Kind {rational, complex}; + +struct Rational { // rationale Zahl + int n; int d; +} ; + +struct Complex { // komplexe Zahl + float re; float im; +} ; + +union Combination { // vereinige beide + Rational p; Complex c; +} ; + +struct Mixed { // gemischte Zahl + Kind a; // welche bist Du? + Combination com; // benutze je nach Art +} ; diff --git a/ws2019/ipi/cpp_headers/montecarlo1.cc b/ws2019/ipi/cpp_headers/montecarlo1.cc new file mode 100644 index 0000000..49a5e44 --- /dev/null +++ b/ws2019/ipi/cpp_headers/montecarlo1.cc @@ -0,0 +1,46 @@ +#include "fcpp.hh" + +unsigned int x = 93267; + +unsigned int zufall () +{ + unsigned int ia = 16807, im = 2147483647; + unsigned int iq = 127773, ir = 2836; + unsigned int k; + + k = x/iq; // LCG xneu=(a*xalt) mod m + x = ia*(x-k*iq)-ir*k; // a = 7^5, m = 2^31-1 + if (x<0) x = x+im; // keine lange Arithmetik + return x; // s. Numerical Recipes +} // in C, Kap. 7. + +unsigned int ggT (unsigned int a, unsigned int b) +{ + if (b==0) return a; + else return ggT(b,a%b); +} + +int experiment () +{ + unsigned int x1,x2; + + x1 = zufall(); x2 = zufall(); + if (ggT(x1,x2)==1) + return 1; + else + return 0; +} + +double montecarlo (int N) +{ + int erfolgreich=0; + + for (int i=0; i1E-12) + x = 0.5*(x+a/x); + return x; + } + +int main () +{ + return print(wurzel(2.0)); +} diff --git a/ws2019/ipi/cpp_headers/quadrat.cc b/ws2019/ipi/cpp_headers/quadrat.cc new file mode 100644 index 0000000..194282f --- /dev/null +++ b/ws2019/ipi/cpp_headers/quadrat.cc @@ -0,0 +1,11 @@ +#include "fcpp.hh" + +int quadrat (int x) +{ + return x*x; +} + +int main () +{ + return print( quadrat(3)+quadrat(4+4) ); +} diff --git a/ws2019/ipi/cpp_headers/quadratfunktion.cc b/ws2019/ipi/cpp_headers/quadratfunktion.cc new file mode 100644 index 0000000..ef196ea --- /dev/null +++ b/ws2019/ipi/cpp_headers/quadratfunktion.cc @@ -0,0 +1,5 @@ + int quadrat (int x) + { + return x*x; + } + diff --git a/ws2019/ipi/cpp_headers/queens.cc b/ws2019/ipi/cpp_headers/queens.cc new file mode 100644 index 0000000..80fe29d --- /dev/null +++ b/ws2019/ipi/cpp_headers/queens.cc @@ -0,0 +1,56 @@ +#include "fcpp.hh" +#include + +const int board_size = 8; // globale Konstante +typedef int columns[board_size]; // neuer Datentyp "columns" + +bool good_position (int new_row, columns queen_cols, int new_col) +{ + for (int row=0; row +#include + +const double pi = 3.1415926536; + +class Shape +{ +public: + virtual ~Shape () {}; + virtual double area () = 0; + virtual double diameter () = 0; + virtual double circumference () = 0; +}; + +// works on every shape +double circumference_to_area (Shape &shape) { + return shape.circumference()/shape.area(); +} + +class Circle : public Shape { +public: + Circle (double r) {radius = r;} + virtual double area () { + return pi*radius*radius; + } + virtual double diameter () { + return 2*radius; + } + virtual double circumference () { + return 2*pi*radius; + } +private: + double radius; +}; + +class Rectangle : public Shape { +public: + Rectangle (double aa, double bb) { + a = aa; b = bb; + } + virtual double area () {return a*b;} + virtual double diameter () { + return sqrt(a*a+b*b); + } + virtual double circumference () { + return 2*(a+b); + } +private: + double a, b; +}; + +int main () +{ + Rectangle unit_square(1.0, 1.0); + Circle unit_circle(1.0); + Circle unit_area_circle(1.0/sqrt(pi)); + + std::cout << "Das Verhältnis von Umfang zu Fläche beträgt\n"; + std::cout << "Einheitsquadrat: " + << circumference_to_area(unit_square) + << std::endl; + std::cout << "Kreis mit Fläche 1: " + << circumference_to_area(unit_area_circle) + << std::endl; + std::cout << "Einheitskreis: " + << circumference_to_area(unit_circle) + << std::endl; + return 0; +} diff --git a/ws2019/ipi/cpp_headers/stack1.cc b/ws2019/ipi/cpp_headers/stack1.cc new file mode 100644 index 0000000..e9aeb83 --- /dev/null +++ b/ws2019/ipi/cpp_headers/stack1.cc @@ -0,0 +1,39 @@ +#include "fcpp.hh" + +typedef int element_type; // Integer-Stack + +// START stack-library ... + +const int stack_size = 1000; + +element_type stack[stack_size]; +int top = 0; // Stapelzeiger + +// Stack-Operationen + +void push (element_type e) +{ + stack[top] = e; + top = top+1; +} + +bool empty () +{ + return top==0; +} + +element_type pop () +{ + top = top-1; + return stack[top]; +} + +int main () +{ + push(4); + push(5); + while (!empty()) + print(pop()); + return 0; +} + diff --git a/ws2019/ipi/cpp_headers/timestamp.cc b/ws2019/ipi/cpp_headers/timestamp.cc new file mode 100644 index 0000000..9f7c6cb --- /dev/null +++ b/ws2019/ipi/cpp_headers/timestamp.cc @@ -0,0 +1,10 @@ +#include +// Setzt Marke und gibt Zeitdifferenz zur letzten Marke zurueck +clock_t last_time; +double time_stamp () { + clock_t current_time = clock(); + double duration = + ((double)(current_time-last_time)) / CLOCKS_PER_SEC; + last_time = current_time; + return duration; +} diff --git a/ws2019/ipi/cpp_headers/useintset.cc b/ws2019/ipi/cpp_headers/useintset.cc new file mode 100644 index 0000000..7e53fe6 --- /dev/null +++ b/ws2019/ipi/cpp_headers/useintset.cc @@ -0,0 +1,20 @@ +#include "fcpp.hh" +#include "intlist.cc" +#include "intset.cc" + +int main () +{ + IntSet* s = empty_set(); + + print_set(s); + + for (int i=1; i<12; i=i+1) + insert_in_set(s,i); + + print_set(s); + + for (int i=2; i<30; i=i+2) + remove_from_set(s,i); + + print_set(s); +} diff --git a/ws2019/ipi/cpp_headers/wechselgeld.cc b/ws2019/ipi/cpp_headers/wechselgeld.cc new file mode 100644 index 0000000..8ccb8d9 --- /dev/null +++ b/ws2019/ipi/cpp_headers/wechselgeld.cc @@ -0,0 +1,29 @@ +#include "fcpp.hh" + +// uebersetze Muenzart in Muenzwert +int nennwert (int nr) +{ + return cond(nr==1, 1, + cond(nr==2, 2, + cond(nr==3, 5, + cond(nr==4, 10, + cond(nr==5, 20, + cond(nr==6, 50, 0)))))); +} + +int wg (int betrag, int muenzarten) +{ + return cond(betrag==0, 1, + cond(betrag<0 || muenzarten==0, 0, + wg(betrag,muenzarten-1) + + wg(betrag-nennwert(muenzarten),muenzarten))); +} + +int wechselgeld (int betrag) +{ + return wg(betrag,6); +} + +int main (int argc, char** argv) { + return print(wechselgeld(readarg_int(argc,argv,1))); +} diff --git a/ws2019/ipi/cpp_headers/wg-stack.cc b/ws2019/ipi/cpp_headers/wg-stack.cc new file mode 100644 index 0000000..e9d399d --- /dev/null +++ b/ws2019/ipi/cpp_headers/wg-stack.cc @@ -0,0 +1,55 @@ +#include "fcpp.hh" + +int nennwert (int nr) {// Muenzart -> Muenzwert + if (nr==1) return 1; if (nr==2) return 2; + if (nr==3) return 5; if (nr==4) return 10; + if (nr==5) return 50; + return 0; +} + +struct Arg { // Stapelelemente + int betrag; // das sind die Argumente der + int muenzarten; };// rekursiven Variante + +const int N = 1000; // Stapelgroesse + +int wechselgeld2 (int betrag) { + Arg stapel[N]; // hier ist der Stapel + int i=0; // der "stack pointer" + int anzahl=0; // das Ergebnis + int b,m; // Hilfsvariablen in Schleife + + stapel[i].betrag = betrag; // initialisiere St. + stapel[i].muenzarten = 5; // Startwert + i = i+1; // ein Element mehr + + while (i>0) { // Solange Stapel nicht leer + i = i-1; // lese oberstes Element + b = stapel[i].betrag;// lese Argumente + m = stapel[i].muenzarten; + + if ( b==0 ) + anzahl = anzahl+1; // Moeglichkeit gefunden + else if ( b>0 && m>0 ) { + if (i>=N) { + print("Stapel zu klein"); + return anzahl; + } + stapel[i].betrag = b; // Betrag b + stapel[i].muenzarten = m-1;// mit m-1 Muenzarten + i = i+1; + + if (i>=N) {print("Stapel zu klein"); return anzahl;} + stapel[i].betrag = b-nennwert(m); + stapel[i].muenzarten = m; // mit m Muenzarten + i = i+1; + } + } + + return anzahl; // Stapel ist jetzt leer +} + +int main () { + print(wechselgeld2(300)); +} + diff --git a/ws2019/ipi/uebung2.cpp b/ws2019/ipi/uebung2.cpp new file mode 100644 index 0000000..5e05b93 --- /dev/null +++ b/ws2019/ipi/uebung2.cpp @@ -0,0 +1,49 @@ +#include "cpp_headers/fcpp.hh" + +// prueft ob Zahl gerade oder nicht +int iseven(int n) { + return n % 2 == 0; +} + +// berechnet Quadrat einer Zahl +int square(int x) { + return x * x; +} + +// berechnet x^exp schnell +int potenz(int x, int exp) { + return cond(exp == 1, // falls exp == 1 + x, // x^1 = x + cond(iseven(exp), + square(potenz(x, exp / 2)), // wenn gerade + x * potenz(x, exp-1))); // wenn ungerade +} + +// summiert alle echten Teiler einer zahl auf +int summiereTeiler(int summe, int index, int zahl) { + // der index stellt den aktuellen zu pruefenden Teiler dar + // falls dieser groeßer ist als die Haelfte der Zahl, kann es keine + // echten Teiler mehr geben, d.h. es wird die aktuelle Summe zurueckgegeben + return cond(index > zahl / 2, + summe, + // falls index die zahl teilt, wird die Summe um index erhöht + // danach wird der nächste moegliche Teiler geprueft + summiereTeiler(cond(zahl % index == 0, summe + index, summe), + index + 1, + zahl)); +} + +// berechnet ob eine Zahl vollkommen ist +bool vollkommen(int zahl) { + // summiere alle Teiler und pruefe ob die Zahl gleich dieses Summe + // es wird mit der Startsumme 0 und dem ersten Teiler 1 gestartet + return summiereTeiler(0, 1, zahl) == zahl; +} + +int main() { + return print(potenz(2, 10), + cond(vollkommen(8128), + "8128 ist vollkommen", + "8128 ist nicht vollkommen"), + 0); +}