| @@ -0,0 +1,4 @@ | |||
| * | |||
| !*.* | |||
| !*/ | |||
| @@ -0,0 +1,7 @@ | |||
| #include "fcpp.hh" | |||
| int main () | |||
| { | |||
| for (int i=32; i<=127; i=i+1) | |||
| print(i,(char) i,0); | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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); | |||
| } | |||
| @@ -0,0 +1,89 @@ | |||
| #include<iostream> | |||
| #include<cassert> | |||
| #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); | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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<n; i=i+1) a[i] = 0; // nix angeschlossen | |||
| b = c = 0; // nix angeschlossen | |||
| w.ConnectInput(*this,0); // Ich -> 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 && pin<n) a[pin] = &w; | |||
| if (pin==n) b = &w; | |||
| } | |||
| void Analyzer::ConnectOutput (Wire& w, int pin) | |||
| { | |||
| // Wird von Connect-Funktion des Drahtes aufgerufen | |||
| c = &w; | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| class And : public Circuit { | |||
| public: | |||
| And (); | |||
| // Konstruktor | |||
| ~And (); | |||
| // 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 | |||
| } ; | |||
| @@ -0,0 +1,49 @@ | |||
| And::And() | |||
| { | |||
| a=b=c=0; // nix angschlossen | |||
| actionFlag=false; | |||
| } | |||
| And::~And() {} | |||
| void And::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 And::Action () | |||
| { | |||
| // Lese Eingangssignale | |||
| State A = a->GetState(); | |||
| 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; | |||
| } | |||
| @@ -0,0 +1,96 @@ | |||
| template <class T> 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<T>; | |||
| } ; | |||
| // 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<T>&); | |||
| Array<T>& operator= (const Array<T>&); | |||
| ~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 <class T> | |||
| Array<T>::Array (const Array<T>& a) { | |||
| n = a.n; | |||
| p = new T[n]; | |||
| for (int i=0; i<n; i=i+1) | |||
| p[i]=a.p[i]; | |||
| } | |||
| // Zuweisung | |||
| template <class T> | |||
| Array<T>& Array<T>::operator= (const Array<T>& a) { | |||
| if (&a!=this) { | |||
| if (n!=a.n) { | |||
| delete[] p; | |||
| n = a.n; | |||
| p = new T[n]; | |||
| } | |||
| for (int i=0; i<n; i=i+1) p[i]=a.p[i]; | |||
| } | |||
| return *this; | |||
| } | |||
| // Ausgabe | |||
| template <class T> | |||
| std::ostream& operator<< (std::ostream& s, Array<T>& a) { | |||
| s << "array " << a.size() << | |||
| " elements = [" << std::endl; | |||
| for (int i=0; i<a.size(); i++) | |||
| s << " " << i << " " << a[i] << std::endl; | |||
| s << "]" << std::endl; | |||
| return s; | |||
| } | |||
| @@ -0,0 +1,71 @@ | |||
| Band::Band (std::string s, char init) | |||
| { | |||
| // initialisiere Band mit dem Symbol init | |||
| for (int i=0; i<Band::N; i++) band[i] = init; | |||
| // Lese Zeichenkette | |||
| if (s.size()>Band::N) | |||
| { | |||
| print("Band zu klein"); | |||
| return; | |||
| } | |||
| for (int i=0; i<s.size(); i++) band[i] = s[i]; | |||
| print(s.size()," Symbole auf Band initialisiert ",0); | |||
| // Setze aktuelle Bandposition auf Anfang | |||
| pos = 0; | |||
| // Initialisiere maximal benutzten Bandabschnitt | |||
| benutzt = s.size(); | |||
| } | |||
| char Band::lese () | |||
| { | |||
| return band[pos]; | |||
| } | |||
| void Band::schreibe_links (char symbol) | |||
| { | |||
| if (pos<0) | |||
| { | |||
| print("Versuch ueber linkes Bandende zu laufen!"); | |||
| return; | |||
| } | |||
| band[pos] = symbol; | |||
| if (pos>=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<pos; i++) { | |||
| kopie[j] = band[i]; | |||
| j = j+1; | |||
| } | |||
| kopie[j] = '['; | |||
| kopie[j+1] = band[pos]; | |||
| kopie[j+2] = ']'; | |||
| j = j+3; | |||
| for (int i=pos+1; i<benutzt; i++) { | |||
| kopie[j] = band[i]; | |||
| j = j+1; | |||
| } | |||
| kopie[j] = 0; // Ende Zeichen | |||
| print(kopie); | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| // Klasse fuer ein linksseitig begrenztes Band | |||
| // einer Turingmaschine. | |||
| // Das Band wird durch eine Zeichenkette aus | |||
| // Elemente des Typs char realisiert | |||
| class Band { | |||
| public: | |||
| // Initialisiere Band mit s, fuelle Rest | |||
| // mit dem Zeichen init auf. | |||
| // Setze aktuelle Bandposition auf linkes Ende. | |||
| Band (std::string s, char init); | |||
| // Lese Symbol unter dem Lesekopf | |||
| char lese (); | |||
| // Schreibe und gehe links | |||
| void schreibe_links (char symbol); | |||
| // Schreibe und gehe rechts | |||
| void schreibe_rechts (char symbol); | |||
| // Drucke aktuellen Bandinhalt bis zur | |||
| // maximal benutzten Position | |||
| void drucke (); | |||
| private: | |||
| enum {N=100000}; // maximal nutzbare Groesse | |||
| char band[N]; // das Band | |||
| int pos; // aktuelle Position | |||
| int benutzt; // bisher beschriebener Teil | |||
| } ; | |||
| @@ -0,0 +1,16 @@ | |||
| template <class C> | |||
| 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<a[m]) | |||
| r = m; | |||
| else | |||
| l = m; | |||
| } | |||
| } | |||
| @@ -0,0 +1,7 @@ | |||
| template <class C> | |||
| void bubblesort (C& a) { | |||
| for (int i=a.size()-1; i>=0; i--) | |||
| for (int j=0; j<i; j=j+1) | |||
| if (a[j+1]<a[j]) | |||
| std::swap(a[j+1], a[j]); | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| #include "fcpp.hh" | |||
| #include <string> | |||
| int main () | |||
| { | |||
| std::string vorname = "Peter"; | |||
| std::string nachname = "Bastian"; | |||
| std::string name = vorname + " " + nachname; | |||
| print(name); | |||
| } | |||
| @@ -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); | |||
| } ; | |||
| @@ -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); | |||
| } | |||
| @@ -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 () {} | |||
| @@ -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 | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -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)); | |||
| } | |||
| @@ -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 | |||
| } | |||
| @@ -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);} | |||
| private: | |||
| int n; // Anzahl Elemente | |||
| int o; // Ursprung der Indexmenge | |||
| float *p; // Zeiger auf built-in array | |||
| } ; | |||
| float& DynamicFloatArray::operator[] (int i) | |||
| { | |||
| if (i<o || i>=o+n) | |||
| { // resize | |||
| int new_o, new_n; | |||
| if (i<o) { | |||
| new_o = i; | |||
| new_n = n+o-i; | |||
| } | |||
| else { | |||
| new_o = o; | |||
| new_n = i-o+1; | |||
| } | |||
| float *q = new float[new_n]; | |||
| for (int i=0; i<new_n; i=i+1) q[i]=0.0; | |||
| for (int i=0; i<n; i=i+1) | |||
| q[i+o-new_o] = p[i]; | |||
| delete[] p; | |||
| p = q; | |||
| n = new_n; | |||
| o = new_o; | |||
| } | |||
| return p[i-o]; | |||
| } | |||
| @@ -0,0 +1,197 @@ | |||
| template<class T> | |||
| 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<T>; // 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<T>& list); | |||
| DLList<T>& operator= (const DLList<T>&); | |||
| ~DLList(); | |||
| // Listenmanipulation | |||
| Iterator insert (Iterator i, T t);// einf. vor i | |||
| void erase (Iterator i); | |||
| void append (const DLList<T>& 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<class T> | |||
| typename DLList<T>::Iterator | |||
| DLList<T>::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<class T> | |||
| void DLList<T>::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<class T> | |||
| void DLList<T>::append (const DLList<T>& l) { | |||
| for (Iterator i=l.begin(); i!=l.end(); i++) | |||
| insert(end(),*i); | |||
| } | |||
| template<class T> | |||
| bool DLList<T>::empty () const { | |||
| return begin()==end(); | |||
| } | |||
| template<class T> | |||
| void DLList<T>::clear () { | |||
| while (!empty()) | |||
| erase(begin()); | |||
| } | |||
| // Constructors | |||
| template<class T> DLList<T>::DLList () {} | |||
| template<class T> | |||
| DLList<T>::DLList (const DLList<T>& list) { | |||
| append(list); | |||
| } | |||
| // Assignment | |||
| template<class T> | |||
| DLList<T>& | |||
| DLList<T>::operator= (const DLList<T>& l) { | |||
| if (this!=&l) { | |||
| clear(); | |||
| append(l); | |||
| } | |||
| return *this; | |||
| } | |||
| // Destructor | |||
| template<class T> DLList<T>::~DLList() { clear(); } | |||
| // Size method | |||
| template<class T> int DLList<T>::size () const { | |||
| int count = 0; | |||
| for (Iterator i=begin(); i!=end(); i++) | |||
| count++; | |||
| return count; | |||
| } | |||
| template<class T> | |||
| typename DLList<T>::Iterator DLList<T>::find (T t) const { | |||
| DLList<T>::Iterator i = begin(); | |||
| while (i!=end()) | |||
| { | |||
| if (*i==t) break; | |||
| i++; | |||
| } | |||
| return i; | |||
| } | |||
| template <class T> | |||
| std::ostream& operator<< (std::ostream& s, DLList<T>& a) { | |||
| s << "("; | |||
| for (typename DLList<T>::Iterator i=a.begin(); | |||
| i!=a.end(); i++) | |||
| { | |||
| if (i!=a.begin()) s << " "; | |||
| s << *i; | |||
| } | |||
| s << ")" << std::endl; | |||
| return s; | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| template<class T> | |||
| class DeQueue : private DLList<T> { | |||
| 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 (); | |||
| } ; | |||
| @@ -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 | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } ; | |||
| @@ -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 | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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); | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| #include <iostream> | |||
| 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<class T> | |||
| 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); | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| #include <iostream> | |||
| 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); | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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); | |||
| } | |||
| @@ -0,0 +1,54 @@ | |||
| template<class T> | |||
| class Heap { | |||
| public: | |||
| bool empty (); | |||
| void push (T x); | |||
| void pop (); | |||
| T top (); | |||
| private: | |||
| std::vector<T> data; | |||
| void reheap (int i); | |||
| } ; | |||
| template<class T> | |||
| void Heap<T>::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 <class T> | |||
| void Heap<T>::reheap (int i) { | |||
| int n = data.size(); | |||
| while (2*i+1<n) | |||
| { | |||
| int l = 2*i+1; | |||
| int r = l+1; | |||
| int k = ((r<n) && (data[r]>data[l])) ? r : l; | |||
| if (data[k]<=data[i]) break; | |||
| std::swap(data[k], data[i]); | |||
| i = k; | |||
| } | |||
| } | |||
| template<class T> | |||
| void Heap<T>::pop () { | |||
| std::swap(data.front(), data.back()); | |||
| data.pop_back(); | |||
| reheap(0); | |||
| } | |||
| template<class T> | |||
| T Heap<T>::top () { | |||
| return data[0]; | |||
| } | |||
| template<class T> | |||
| inline bool Heap<T>::empty () { | |||
| return data.size()==0; | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| template <class C> | |||
| inline void reheap (C& a, int n, int i) { | |||
| while (2*i+1<n) | |||
| { | |||
| int l = 2*i+1; | |||
| int r = l+1; | |||
| int k = ((r<n) && (a[r]>a[l])) ? r : l; | |||
| if (a[k]<=a[i]) break; | |||
| std::swap(a[k], a[i]); | |||
| i = k; | |||
| } | |||
| } | |||
| template <class C> | |||
| 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); | |||
| } | |||
| } | |||
| @@ -0,0 +1,115 @@ | |||
| #include <iostream> | |||
| #include <map> | |||
| #include <queue> | |||
| #include <string> | |||
| 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<char,int> 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<node, vector<node>, greater<node> > q; | |||
| for (map<char,int>::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<char,string>& 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<char,string> 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<char,string> table; | |||
| fill_encoding_table ("", trie, table); | |||
| for (map<char,string>::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 ... | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| template <class C> | |||
| void insertionsort (C& a) { | |||
| for (int i=1; i<a.size(); i=i+1) { | |||
| // i Elemente sind sortiert | |||
| int j=i; | |||
| while (j>0 && a[j-1]>a[j]) { | |||
| std::swap(a[j], a[j-1]); | |||
| j=j-1; | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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->index<min) min=q->index; | |||
| 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); | |||
| } | |||
| @@ -0,0 +1,41 @@ | |||
| #include<iostream> | |||
| #include<cassert> | |||
| #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); | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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->index<min) min=q->index; | |||
| 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; | |||
| } | |||
| @@ -0,0 +1,73 @@ | |||
| template<class T> | |||
| 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<T>; | |||
| }; | |||
| 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<T>& l) {}; | |||
| List<T>& operator= (const List<T>& l) {}; | |||
| }; | |||
| template<class T> List<T>::~List() | |||
| { | |||
| Link* p = _first; | |||
| while (p!=0) | |||
| { | |||
| Link* q = p; | |||
| p = p->next(); | |||
| delete q; | |||
| } | |||
| } | |||
| template<class T> | |||
| void List<T>::insert (List<T>::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<class T> | |||
| void List<T>::remove (List<T>::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; | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| // Existiert schon als std::pair | |||
| // template<class Key, class T> | |||
| // struct pair { | |||
| // Key first; | |||
| // T second; | |||
| // } ; | |||
| template<class Key, class T> | |||
| class Map : private DLList<pair<Key,T> > { | |||
| public : | |||
| T& operator[](const Key& k); | |||
| typedef typename DLList<pair<Key,T> >::Iterator Iterator; | |||
| Iterator begin () const; | |||
| Iterator end () const; | |||
| Iterator find (const Key& k); | |||
| } ; | |||
| @@ -0,0 +1,29 @@ | |||
| template <class C> | |||
| 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<n; k=k+1) | |||
| if ((i2>=o+n) || (i1<o+n1 && a[i1]<=a[i2])) | |||
| b[k] = a[i1++]; | |||
| else | |||
| b[k] = a[i2++]; | |||
| // umkopieren | |||
| for (int k=0; k<n; k=k+1) a[o+k] = b[k]; | |||
| } | |||
| template <class C> | |||
| void mergesort (C& a) | |||
| { | |||
| rec_merge_sort(a,0,a.size()); | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| template<class T> | |||
| class MinPriorityQueue : public DLList<T> { | |||
| private: | |||
| typename DLList<T>::Iterator find_minimum(); | |||
| public : | |||
| // Default-Konstruktoren + Zuweisung OK | |||
| bool empty (); | |||
| void push (T t); // Einfuegen | |||
| void pop (); // Entferne kleinstes | |||
| T top (); // Inspiziere kleinstes | |||
| } ; | |||
| @@ -0,0 +1,29 @@ | |||
| template<class T> | |||
| bool MinPriorityQueue<T>::empty () { | |||
| return DLList<T>::empty(); | |||
| } | |||
| template<class T> | |||
| void MinPriorityQueue<T>::push (T t) { | |||
| this->insert(DLList<T>::begin(),t); | |||
| } | |||
| template<class T> | |||
| typename DLList<T>::Iterator | |||
| MinPriorityQueue<T>::find_minimum () { | |||
| typename DLList<T>::Iterator min=DLList<T>::begin(); | |||
| for (typename DLList<T>::Iterator i=DLList<T>::begin(); | |||
| i!=DLList<T>::end(); i++) | |||
| if (*i<*min) min=i; | |||
| return min; | |||
| } | |||
| template<class T> | |||
| inline void MinPriorityQueue<T>::pop () { | |||
| this->erase(find_minimum()); | |||
| } | |||
| template<class T> | |||
| inline T MinPriorityQueue<T>::top () { | |||
| return *find_minimum(); | |||
| } | |||
| @@ -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; i<N; i=i+1) | |||
| erfolgreich = erfolgreich+e.durchfuehren(); | |||
| return ((double)erfolgreich)/((double)N); | |||
| } | |||
| int main (int argc, char** argv) | |||
| { | |||
| Zufall z(93267); // ein Zufallsgenerator | |||
| Experiment e(z); // ein Experiment | |||
| print(sqrt(6.0/montecarlo(e,readarg_int(argc,argv,1)))); | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| class Nand : public Circuit { | |||
| public: | |||
| // Konstruktor | |||
| Nand (); | |||
| // default destructor ist OK | |||
| ~Nand (); | |||
| // 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 1 | |||
| Wire* b; // Eingang 2 | |||
| Wire* c; // Ausgang | |||
| bool actionFlag; // merke ob bereits aktiviert | |||
| } ; | |||
| @@ -0,0 +1,48 @@ | |||
| Nand::Nand() | |||
| { | |||
| a=b=c=0; // nix angschlossen | |||
| actionFlag=false; | |||
| } | |||
| Nand::~Nand() {} | |||
| void Nand::ChangeInput (State s, int pin) | |||
| { | |||
| // Sorge dafuer, dass Gatter neu berechnet wird | |||
| if (!actionFlag) | |||
| { | |||
| Sim.StoreCircuitEvent(*this); | |||
| actionFlag=true; | |||
| } | |||
| } | |||
| void Nand::Action () | |||
| { | |||
| // Lese Eingangssignale | |||
| State A = a->GetState(); | |||
| 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; | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -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 (); | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||
| 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; | |||
| } | |||
| @@ -0,0 +1,2 @@ | |||
| Polynomial::Polynomial (int n) | |||
| : SimpleFloatArray(n+1,0.0) {} | |||
| @@ -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<zeilen; i=i+1) | |||
| if ( Qaktuell[i]==q && eingabe[i]==symbol ) | |||
| { | |||
| letzteZeile = i; | |||
| letztesQ = Qaktuell[letzteZeile]; | |||
| letzteEingabe = eingabe[letzteZeile]; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| @@ -0,0 +1,51 @@ | |||
| // Eine Klasse, die das Programm einer | |||
| // Turingmaschine realisiert. | |||
| // Zustaende sind vom Typ int | |||
| // Bandalphabet ist der Typ char | |||
| // Anfangszustand ist Zustand in der ersten Zeile | |||
| // Endzustand ist Zustand in der letzten Zeile | |||
| class Programm { | |||
| public: | |||
| // Symbole fuer links/rechts | |||
| enum R {links,rechts}; | |||
| // Erzeuge leeres Programm | |||
| Programm (); | |||
| // definiere Zustandsuebergaenge | |||
| // Mit Angabe des Endzustandes ist die | |||
| // Programmierphase beendet | |||
| void zeile (int q_ein, char s_ein, | |||
| char s_aus, R richt, int q_aus); | |||
| void zeile (int endzustand); | |||
| // lese Zustandsuebergang in Abhaengigkeit | |||
| // von akt. Zustand und gelesenem Symbol | |||
| char Ausgabe (int zustand, char symbol); | |||
| R Richtung (int zustand, char symbol); | |||
| int Folgezustand (int zustand, char symbol); | |||
| // Welcher Zustand ist Anfangszustand | |||
| int Anfangszustand (); | |||
| // Welcher Zustand ist Endzustand | |||
| int Endzustand (); | |||
| private: | |||
| // Finde die Zeile zu geg. Zustand/Symbol | |||
| // Liefere true, falls so eine Zeile gefunden | |||
| // wird, sonst false | |||
| bool FindeZeile(int zustand, char symbol); | |||
| enum {N=1000}; // maximale Anzahl Uebergaenge | |||
| int zeilen; // Anzahl Zeilen in Tabelle | |||
| bool fertig; // Programmierphase beendet | |||
| int Qaktuell[N]; // Eingabezustand | |||
| char eingabe[N]; // Eingabesymbol | |||
| char ausgabe[N]; // Ausgabesymbol | |||
| R richtung[N]; // Ausgaberichtung | |||
| int Qfolge[N]; // Folgezustand | |||
| int letztesQ; // Merke Eingabe und Zeilen- | |||
| int letzteEingabe;// nummer des letzten Zu- | |||
| int letzteZeile; // griffes. | |||
| } ; | |||
| @@ -0,0 +1,55 @@ | |||
| template<class T> | |||
| 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<T>& y) { | |||
| p = y.p; | |||
| if (p!=0) increment(); | |||
| } | |||
| ~Ptr () { | |||
| if (p!=0) decrement(); | |||
| } | |||
| Ptr<T>& operator= (const Ptr<T>& 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; } | |||
| }; | |||
| @@ -0,0 +1,19 @@ | |||
| #include<iostream> | |||
| #include"Ptr.hh" | |||
| int g (Ptr<int> p) { | |||
| return *p; | |||
| } | |||
| int main () | |||
| { | |||
| Ptr<int> q = new int(17); | |||
| std::cout << *q << std::endl; | |||
| int x = g(q); | |||
| std::cout << x << std::endl; | |||
| Ptr<int> z = new int(22); | |||
| q = z; | |||
| std::cout << *q << std::endl; | |||
| // nun wird alles automatisch geloescht ! | |||
| } | |||
| @@ -0,0 +1,20 @@ | |||
| template<class T> | |||
| class Queue : public DLList<T> { | |||
| public : | |||
| // Default-Konstruktoren + Zuweisung OK | |||
| bool empty () { | |||
| return DLList<T>::empty(); | |||
| } | |||
| T front () { | |||
| return *DLList<T>::begin(); | |||
| } | |||
| T back () { | |||
| return *DLList<T>::rbegin(); | |||
| } | |||
| void push (T t) { | |||
| this->insert(DLList<T>::end(),t); | |||
| } | |||
| void pop () { | |||
| this->erase(DLList<T>::begin()); | |||
| } | |||
| } ; | |||
| @@ -0,0 +1,30 @@ | |||
| template <class C> | |||
| 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<j) { | |||
| i=i+1; while (i<j && a[i]<=a[q]) i=i+1; | |||
| j=j-1; while (i<j && a[j]>=a[q]) j=j-1; | |||
| if (i<j) | |||
| std::swap(a[i],a[j]); | |||
| else | |||
| std::swap(a[i],a[q]); | |||
| } | |||
| return i; // endgueltige Position des Pivot | |||
| } | |||
| template <class C> | |||
| void qs_rec (C& a, int l, int r) { | |||
| if (l<r) { | |||
| int i=qs_partition(a,l,r,r); | |||
| qs_rec(a,l,i-1); | |||
| qs_rec(a,i+1,r); | |||
| } | |||
| } | |||
| template <class C> | |||
| void quicksort (C& a) { | |||
| qs_rec(a,0,a.size()-1); | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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); | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| std::ostream& | |||
| operator<< (std::ostream& s, Rational q) | |||
| { | |||
| s << q.numerator() << "/" << q.denominator(); | |||
| return s; | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| template <class C> | |||
| void selectionsort (C& a) | |||
| { | |||
| for (int i=0; i<a.size()-1; i=i+1) | |||
| { // i Elemente sind sortiert | |||
| int min = i; | |||
| for (int j=i+1; j<a.size(); j=j+1) | |||
| if (a[j]<a[min]) min=j; | |||
| std::swap(a[i],a[min]); | |||
| } | |||
| } | |||
| @@ -0,0 +1,15 @@ | |||
| template<class T> | |||
| class Set : private DLList<T> { | |||
| public : | |||
| // Default-Konstruktoren + Zuweisung OK | |||
| typedef typename DLList<T>::Iterator Iterator; | |||
| Iterator begin(); | |||
| Iterator end(); | |||
| bool empty (); | |||
| bool member (T t); | |||
| void insert (T t); | |||
| void remove (T t); | |||
| // union, intersection, ... ? | |||
| } ; | |||
| @@ -0,0 +1,34 @@ | |||
| template<class T> | |||
| typename Set<T>::Iterator Set<T>::begin() { | |||
| return DLList<T>::begin(); | |||
| } | |||
| template<class T> | |||
| typename Set<T>::Iterator Set<T>::end() { | |||
| return DLList<T>::end(); | |||
| } | |||
| template<class T> | |||
| bool Set<T>::empty () { | |||
| return DLList<T>::empty(); | |||
| } | |||
| template<class T> | |||
| inline bool Set<T>::member (T t) { | |||
| return find(t)!=DLList<T>::end(); | |||
| } | |||
| template<class T> | |||
| inline void Set<T>::insert (T t) | |||
| { | |||
| if (!member(t)) | |||
| DLList<T>::insert(DLList<T>::begin(),t); | |||
| } | |||
| template<class T> | |||
| inline void Set<T>::remove (T t) | |||
| { | |||
| typename DLList<T>::Iterator i = find(t); | |||
| if (i!=DLList<T>::end()) | |||
| erase(i); | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| template <class T> | |||
| class SimpleArray { | |||
| public: | |||
| SimpleArray (int s, T f); | |||
| SimpleArray (const SimpleArray<T>&); | |||
| SimpleArray<T>& operator= | |||
| (const SimpleArray<T>&); | |||
| ~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 | |||
| } ; | |||
| @@ -0,0 +1,27 @@ | |||
| template <class T, int m> | |||
| 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 | |||
| } ; | |||
| @@ -0,0 +1,35 @@ | |||
| template <class T, int m> | |||
| inline SimpleArrayCS<T,m>::SimpleArrayCS (T v) | |||
| { | |||
| for (int i=0; i<m; i=i+1) p[i]=v; | |||
| } | |||
| template <class T, int m> | |||
| inline T& SimpleArrayCS<T,m>::operator[] (int i) | |||
| { | |||
| return p[i]; | |||
| } | |||
| template <class T, int m> | |||
| inline int SimpleArrayCS<T,m>::numIndices () { return m; } | |||
| template <class T, int m> | |||
| inline int SimpleArrayCS<T,m>::minIndex () { return 0; } | |||
| template <class T, int m> | |||
| inline int SimpleArrayCS<T,m>::maxIndex () { return m-1; } | |||
| template <class T, int m> | |||
| inline bool SimpleArrayCS<T,m>::isMember (int i) | |||
| { | |||
| if (i>=0 && i<m) return true; | |||
| else return false; | |||
| } | |||
| template <class T, int m> | |||
| std::ostream& operator<< (std::ostream& s, SimpleArrayCS<T,m>& a) | |||
| { | |||
| for (int i=a.minIndex(); i<=a.maxIndex(); i=i+1) | |||
| s << i << " " << a[i] << std::endl; | |||
| return s; | |||
| } | |||
| @@ -0,0 +1,81 @@ | |||
| // Destruktor | |||
| template <class T> | |||
| SimpleArray<T>::~SimpleArray () { | |||
| delete[] p; | |||
| } | |||
| // Konstruktor | |||
| template <class T> | |||
| SimpleArray<T>::SimpleArray (int s, T v) | |||
| { | |||
| n = s; | |||
| p = new T[n]; | |||
| for (int i=0; i<n; i=i+1) p[i]=v; | |||
| } | |||
| // Copy-Konstruktor | |||
| template <class T> | |||
| SimpleArray<T>::SimpleArray (const | |||
| SimpleArray<T>& a) { | |||
| n = a.n; | |||
| p = new T[n]; | |||
| for (int i=0; i<n; i=i+1) | |||
| p[i]=a.p[i]; | |||
| } | |||
| // Zuweisungsoperator | |||
| template <class T> | |||
| SimpleArray<T>& SimpleArray<T>::operator= | |||
| (const SimpleArray<T>& a) | |||
| { | |||
| if (&a!=this) { | |||
| if (n!=a.n) { | |||
| delete[] p; | |||
| n = a.n; | |||
| p = new T[n]; | |||
| } | |||
| for (int i=0; i<n; i=i+1) p[i]=a.p[i]; | |||
| } | |||
| return *this; | |||
| } | |||
| template <class T> | |||
| inline T& SimpleArray<T>::operator[] (int i) | |||
| { | |||
| return p[i]; | |||
| } | |||
| template <class T> | |||
| inline int SimpleArray<T>::numIndices () | |||
| { | |||
| return n; | |||
| } | |||
| template <class T> | |||
| inline int SimpleArray<T>::minIndex () | |||
| { | |||
| return 0; | |||
| } | |||
| template <class T> | |||
| inline int SimpleArray<T>::maxIndex () | |||
| { | |||
| return n-1; | |||
| } | |||
| template <class T> | |||
| inline bool SimpleArray<T>::isMember (int i) | |||
| { | |||
| return (i>=0 && i<n); | |||
| } | |||
| template <class T> | |||
| std::ostream& operator<< (std::ostream& s, | |||
| SimpleArray<T>& a) | |||
| { | |||
| s << "#( "; | |||
| for (int i=a.minIndex(); i<=a.maxIndex(); i=i+1) | |||
| s << a[i] << " "; | |||
| s << ")" << std::endl; | |||
| return s; | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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<n; i=i+1) p[i]=a.p[i]; | |||
| } | |||
| // Gebe Referenz zurueck damit a=b=c klappt | |||
| return *this; | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| SimpleFloatArray::SimpleFloatArray (const SimpleFloatArray& a) { | |||
| n = a.n; | |||
| p = new float[n]; | |||
| for (int i=0; i<n; i=i+1) | |||
| p[i]=a.p[i]; | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| SimpleFloatArray::SimpleFloatArray (int s, | |||
| float v) | |||
| { | |||
| n = s; | |||
| try { | |||
| p = new float[n]; | |||
| } | |||
| catch (std::bad_alloc) { | |||
| n = 0; | |||
| throw; | |||
| } | |||
| for (int i=0; i<n; i=i+1) p[i]=v; | |||
| } | |||
| SimpleFloatArray::~SimpleFloatArray () { delete[] p; } | |||
| int SimpleFloatArray::numIndices () { return n; } | |||
| int SimpleFloatArray::minIndex () { return 0; } | |||
| int SimpleFloatArray::maxIndex () { return n-1; } | |||
| bool SimpleFloatArray::isMember (int i) | |||
| { | |||
| return (i>=0 && i<n); | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| float& SimpleFloatArray::operator[] (int i) | |||
| { | |||
| return p[i]; | |||
| } | |||
| @@ -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 | |||
| virtual 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 | |||
| } ; | |||
| @@ -0,0 +1,37 @@ | |||
| // Simulator, Singleton | |||
| class Simulator { | |||
| public: | |||
| // Konstruktor | |||
| Simulator (); | |||
| // aktuelle Zeit auslesen | |||
| int GetTime (); | |||
| // (B): Draht w wird zur Zeit t in Zustand s wechseln | |||
| void StoreWireEvent (Wire& w, int t, State s); | |||
| // (D): Baustein c soll zur aktuellen Zeit neu berechnet werden | |||
| void StoreCircuitEvent (Circuit& c); | |||
| // Starte Simulation bei Zeit 0 | |||
| void Simulate (int end); | |||
| private: | |||
| struct WireEvent { // Eine lokale Struktur | |||
| WireEvent (); // fuer Ereignis "Zustandswechsel" | |||
| WireEvent (Wire& W, int T, State S); | |||
| Wire* w; | |||
| int t; | |||
| State s; | |||
| bool operator< (WireEvent we); | |||
| void print (std::ostream& stm) {stm << "(WE: " << t << " " << w << " " << s << std::endl; } | |||
| } ; | |||
| int time; | |||
| MinPriorityQueue<WireEvent> pq; // Fuer (B)-Ereignisse | |||
| Queue<Circuit*> q; // Fuer (D)-Ereignisse | |||
| } ; | |||
| // Globale Variable vom Typ Simulator (Singleton). | |||
| // Wird von allen Bausteinen und Draehten benutzt! | |||
| Simulator Sim; | |||
| @@ -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<we.t) return true; | |||
| if (t==we.t && (reinterpret_cast<unsigned long int>(w)<reinterpret_cast<unsigned long int>(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; | |||
| } | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| template<class T> | |||
| class Stack : private DLList<T> { | |||
| public : | |||
| // Default-Konstruktoren + Zuweisung OK | |||
| bool empty () {return DLList<T>::empty();} | |||
| void push (T t) { | |||
| this->insert(DLList<T>::begin(),t); | |||
| } | |||
| T top () {return *DLList<T>::begin();} | |||
| void pop () {this->erase(DLList<T>::begin());} | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||
| } ; | |||
| @@ -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 | |||
| } ; | |||
| @@ -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; | |||
| } | |||
| @@ -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. | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| #include<cassert> | |||
| #include<iostream> | |||
| #include"Array.hh" | |||
| #include"DLL.hh" | |||
| #include"Zufall.cc" | |||
| int main () { | |||
| Zufall z(87124); | |||
| Array<int> a(5); | |||
| DLList<int> 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<int>::Iterator i=a.begin(); | |||
| i!=a.end(); i++) | |||
| std::cout << *i << std::endl; | |||
| std::cout << std::endl; | |||
| for (DLList<int>::Iterator i=l.begin(); | |||
| i!=l.end(); i++) | |||
| std::cout << *i << std::endl; | |||
| } | |||
| @@ -0,0 +1,65 @@ | |||
| #include<iostream> | |||
| // 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 <class T> | |||
| void initialisiere (T & a) { | |||
| for (int i=0; i<n; i=i+1) | |||
| a[i] = z.ziehe_zahl(); | |||
| } | |||
| int main () | |||
| { | |||
| SimpleArrayCS<float,n> a(0.0); | |||
| SimpleArray<float> 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; | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| #include<iostream> | |||
| #include<cassert> | |||
| #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; | |||
| } | |||