Join Date: Nov 2007
Location: Leipzig, Germany
Posts: 26
|
It's out to get me, that is the sole explanation! But I can do something it has not planned for, I can suprise it, ha, and I will suprise it: by exposing it to the world!
If anyone feels like having a little bit of unused time and grand need for a headache, mayhap he can take a look at this and tell me, where exactly I... how is it said... "fucked up".
Code:
#include <ostream>
#include "ItemSet.h"
#include "Sortierverfahren.h"
ItemSet::ItemSet(ItemSet * vorhandeneMenge) : vector<string>(*vorhandeneMenge),
istSortiert(vorhandeneMenge->istSortiert),
sollSortiertBleiben(vorhandeneMenge->sollSortiertBleiben),
sortierfunktion(vorhandeneMenge->sortierfunktion)
{}
ItemSet::ItemSet(bool sortiertBleiben,
void (*neueSortierfunktion)(vector<string> * const)) : vector<string>(), istSortiert(true),
sollSortiertBleiben(sortiertBleiben),
sortierfunktion(neueSortierfunktion)
{}
ItemSet::~ItemSet()
{
delete(&(this->istSortiert)); // Keine Ahnung, ob man das überhaupt tun muss...
delete(&(this->sollSortiertBleiben)); // aber wir tun es mal lieber.
this->vector<string>::~vector(); // An dieser Stelle könnte theoretisch auch destroy(this) stehen,
// aber wären die Aufrufe äquivalent?
// Wenn nicht - welcher ist dann der richtige?
}
vector<string>::iterator ItemSet::begin()
{
return this->vector<string>::begin();
}
vector<string>::iterator ItemSet::end()
{
return this->vector<string>::end();
}
void ItemSet::bleibeSortiert(bool sortiertBleiben)
{
this->sollSortiertBleiben = sortiertBleiben;
if(this->sollSortiertBleiben && !this->istSortiert)
{
this->sort();
}
}
void ItemSet::fuegeEin(string gegenstand)
{
if(this->sollSortiertBleiben)
{
// InsertionSort
vector<string>::iterator it = this->begin();
while(it != this->end() && *it > gegenstand)
{
it++;
}
this->insert(it, gegenstand);
}
else
{
this->push_back(gegenstand);
}
}
void ItemSet::nimmSortierfunktion(void (*neueSortierfunktion)(vector<string> * const))
{
this->sortierfunktion = neueSortierfunktion;
}
void ItemSet::sortiere(void (*sortierfunktion)(vector<string> * const))
{
sortierfunktion(this);
this->istSortiert = true;
}
// ist eigentlich Blödsinn... sollte mit this->fuegeEin und vector<string>::push_back getan werden
void ItemSet::push_back(string gegenstand)
{
if(!this->empty())
{
if(this->back() > gegenstand)
{
this->istSortiert = false;
this->sollSortiertBleiben = false;
}
}
this->vector<string>::push_back(gegenstand);
}
void ItemSet::sort()
{
this->sortiere(this->sortierfunktion);
}
string ItemSet::back()
{
return this->vector<string>::back();
}
// sollte aus Symmetriegründen ItemSet * nehmen, aber leider...
unsigned int ItemSet::matches(ItemSet andereMenge, unsigned int bisHier)
{
vector<string>::iterator itA = this->begin();
vector<string>::iterator itB = andereMenge.begin();
unsigned int position = 0;
bool stimmenUeberein = true;
do
{
stimmenUeberein = stimmenUeberein && (*itA == *itB);
itA++;
itB++;
position++;
if(itA == this->end() ^ itB == andereMenge.end()) // Einer von beiden ist am Ende, der andere nicht.
{
stimmenUeberein = false;
}
else if(stimmenUeberein && itA == this->end() && itB == andereMenge.end())
{
position = bisHier; // bisHier wird zurückgegeben, wenn beide übereinstimmen - auch wenn
// mangels ausreichender Länge gar nicht bis dorthin gezählt wurde
}
}
while(stimmenUeberein && position < bisHier);
return position; // Ist das Ergebnis kleiner als bisHier, dann zeigt es das erste Vorkommen eines Unterschiedes.
}
bool ItemSet::contains(ItemSet andereMenge)
{
if(!this->istSortiert)
{
this->sort();
}
if(!andereMenge.istSortiert)
{
andereMenge.sort();
}
if(this->size() < andereMenge.size()) // Das Enthaltende soll kleiner als das Enthaltene sein.
{
return false;
}
else
{
vector<string>::iterator itA = this->begin();
vector<string>::iterator itB = andereMenge.begin();
if(this->size() == andereMenge.size()) // Beide sind gleich groß - ergo müssen sie identisch sein.
{
do
{
if(*itA != *itB)
{
return false;
}
itA++;
itB++;
}
while(itA != this->end());
return true;
}
else // Die Elemente von andereMenge müssen sich in der Reihenfolge
// ihres Auftretens zwischen den Elementen von this verbergen.
{
do
{
while(itA != this->end() && *itA != *itB)
{
itA++; // Wir zählen durch die Elemente von this und vergleichen sie mit einem aus andereMenge.
}
if(itA == this->end() && (*itA != *itB)) // Wir sind am Ende, haben aber ein Element
// aus andereMenge nicht gefunden.
{
return false;
}
else
{
itB++; // Sobald dieses Element gefunden wurde, betrachten wir das nächste.
}
}
while(itB != andereMenge.end()); // Alle Elemente von andereMenge wurden gefunden.
return true;
}
}
}
ItemSet * ItemSet::subset(unsigned int i)
{
ItemSet * untermenge = new ItemSet(this);
if(i < this->size())
{
untermenge->erase(untermenge->begin() + i); // Dadurch sollten wir die Referenz auf die Kopie
// von *(this->begin() + i) verlieren... oder?
}
return untermenge;
}
ostream & operator<<(ostream & ausgabe, ItemSet & menge)
{
vector<string>::iterator it = menge.begin();
while(it != menge.end())
{
ausgabe << *it << ' ';
it++;
}
return ausgabe;
}
ItemSet.cpp
Code:
#include <fstream>
#include "ItemSetContainer.h"
#include "Sortierverfahren.h"
ItemSetContainer::ItemSetContainer() : vector<ItemSet>()
{}
vector<ItemSet>::iterator ItemSetContainer::begin()
{
return this->vector<ItemSet>::begin();
}
vector<ItemSet>::iterator ItemSetContainer::end()
{
return this->vector<ItemSet>::end();
}
void ItemSetContainer::read_from_file(string name)
{
ifstream eingabestrom(name.c_str());
string neueZeile;
do
{
getline(eingabestrom, neueZeile); // Funktion aus der Strings-Bibliothek - ist eleganter als ifstream->getline
if(!neueZeile.empty())
{
char * t;
char * zeile = new char[neueZeile.size() + 1]; // aus algorithmischer Sicht überflüssig...
ItemSet * neueMenge = new ItemSet(false, &Sortierverfahren::bubbleSort); // ItemSet neueMenge erzeugt CTD
// nach Ende der if-Struktur...
// keine Ahnung wie, ist aber so.
if(eingabestrom.eof())
{
neueZeile.push_back(' '); // um sicherzugehen, dass der letzte Rest auch gefunden wird
}
strcpy(zeile, neueZeile.c_str()); // uneleganter Weg, const char * zu char * zu wandeln...
// Nun zerhacken wir unsere Zeile in bester Massenmödermanier in handliche Stückchen.
// Eigentlich könnten wir das auch direkt mit neueZeile tun, aber leider scheint
// es kein C++-Äquivalent zu dieser C-Funktion zu geben.
t = strtok(zeile, " ");
while(t != NULL)
{
neueMenge->push_back(string(t));
// cout << t << " ";
t = strtok(NULL, " ");
// cout << (t != NULL) << " "; // Hier kommen wir nie an, wenn wir als vierte Zeile
// "konrad zuse heinz billing heinz nixdorf" eintragen:
// Nach konrad ist dann Schluss. Keine Ahnung, warum.
}
// cout << endl;
this->push_back(*neueMenge); // funktioniert aus unerfindlichen Gründen
// nicht für Mengen mit identischen Inhalten
// Muss man die Referenzen (t, zeile) jetzt mit delete(void *) bereinigen... oder nicht?
}
}
while(!eingabestrom.eof());
eingabestrom.close();
// Die Destruktoren von eingabestrom und neueZeile werden jetzt automatisch aufgerufen...
// oder wir haben uns verlesen und sie werden es nicht. Was wäre zu tun?
}
ItemSetContainer.cpp
Code:
#include "Sortierverfahren.h"
void Sortierverfahren::quickSort_sortieren(vector<string> * const liste, unsigned int links, unsigned int rechts)
{
if(links < rechts)
{
unsigned int teiler = quickSort_teilen(liste, links, rechts);
quickSort_sortieren(liste, links, teiler - 1);
quickSort_sortieren(liste, teiler + 1, rechts);
}
}
unsigned int Sortierverfahren::quickSort_teilen(vector<string> * const liste, unsigned int links,
unsigned int rechts)
{
unsigned int i = links;
unsigned int j = rechts;
// cout << liste->back() << endl; // Hier hatten wir einen ganz, ganz seltsamen Fehler, den wir uns
// nicht ganz erklären können. Deshalb benutzen wir bubbleSort.
// Lag womöglich am operator<< und ist bereits behoben.
string pivotelement = liste->back();
// cout << "Pivotelement: " << pivotelement << endl; // Bis hierher sind wir nie gekommen...
do
{
while(liste->at(i) <= pivotelement && i < rechts)
{
i++;
}
while(liste->at(j) >= pivotelement && j > links)
{
j--;
}
}
while(i < j);
if(liste->at(i) > pivotelement)
{
string temp = liste->at(j);
// Hier ein Beispiel dafür, welch hässliche Syntax C++ zuweilen zulässt.
liste->at(j) = liste->at(i);
liste->at(i) = temp;
}
return i;
}
void Sortierverfahren::bubbleSort(vector<string> * const liste)
{
bool vertauscht = true;
unsigned int z = liste->size();
while(vertauscht && z >= 1)
{
vertauscht = false;
for(unsigned int i = 0; i < z - 1; i++)
{
if(liste->at(i) > liste->at(i + 1))
{
string temp = liste->at(i);
liste->at(i) = liste->at(i + 1);
liste->at(i + 1) = temp;
vertauscht = true;
}
}
z--;
}
}
void Sortierverfahren::quickSort(vector<string> * const liste)
{
quickSort_sortieren(liste, 0, liste->size() - 1);
}
Sortierverfahren.cpp
The whole thing compiles under Windows and with minimal changes under Linux, but while it works "somewhat" under the former, it does not even do a little under the latter.
|