Grenzen bei verschachtelten Schleifen
-
Hallo
Eigentlich dachte ich, dass ich verschachtelte for Schleifen inzwischen verstanden habe, doch nun stocke ich bei folgendem Problem, was mir zeigt das ich es doch noch nicht wirklich verstanden habe.
Ich habe eine Matrix A mit zwei Zeilen und vier Spalten und eine Matrix B mit vier Zeilen und vier Spalten, bzw. allgemein (r x n)-Matrix A und (s x n)-Matrix B. Nun möchte ich von jedem Zeilenvektor von A und jedem Zeilenvektor von B den Hammingabstand berechnen um zu testen ob Matrix A und B gleiche Zeilenvektoren besitzen (Hamming Abstand Null). Die Abstandsfunktion habe ich ausgegliedert und mit einem Unit Test auf Richtigkeit getestet. Nur bei den Schleifen erhalte ich immer eine Speicherfehler aufgrund der Unterschiedlichen Zeilenzahl von A und B.
Wie würde man hier die Grenzen der for Schleifen richtig testen und ist es evtl. sinnvoller mit einer while und for Schleife zu arbeiten?
Danke für Tipps und Grüße
-
Zwischen for- und while-Schleife besteht eigentlich kein Unterschied.
Du kannst die (fast) jederzeit gegeneinader austauschen.
Initialisierung; while(Bedingung){ Schleifenkörper Inkrement } for(Initialisierung; Bedingung;Inkrement){ Schleifenkörper }Der Unterschied liegt in der Gültigkeit der Schleifenvariablen, wenn du sie erst bei der Initialisierung definierst.
Ohne Code von dir, wird das nichts.
-
Hallo
Danke für deine Antwort. Etwas sehr schönes ist heute passiert. Ich konnte zum ersten mal eigenständig debuggen, indem ich mir immer alle Variable ausgeben ließ und so meine Fehler fand und dadurch sah ich wie man es richtig machen muss. Es läuft jetzt

Falls jemand mal ein ähnliches Problem haben sollte hier mein Code. Falls man etwas besser machen kann würde ich mich über Tipps freuen.
In meinem Header Routine.h
int HammingDistance(std::vector<int> &vecA, std::vector<int> &vecB); void MatricesRowComparison(std::vector< std::vector<int> > &MatrixA, std::vector< std::vector<int> > &MatrixB);Die Source Datei Routine.cpp
// _____________________________________________________________________ // Hamming distance of two vectors int Routine::HammingDistance(std::vector<int> &vecA, std::vector<int> &vecB) { int hm_distance; hm_distance=0; for(size_t i=0; i<vecA.size(); i++){ if(!(vecA[i]==vecB[i])){hm_distance++;} else{hm_distance=hm_distance+0;} } return hm_distance; } // _____________________________________________________________________ // Compare the Hamming distance for each possible row of two matrices void Routine::MatricesRowComparison(std::vector< std::vector<int> > &MatrixA, std::vector< std::vector<int> > &MatrixB) { std::ofstream print("./Output.txt",std::ios_base::app); int rowsA, columnsA, rowsB, dist; rowsA=MatrixA.size(); columnsA=MatrixA[1].size(); rowsB=MatrixB.size(); std::vector<int> vectorsA(columnsA); std::vector<int> vectorsB(columnsA); for(int r=0; r<rowsA; ++r) { for(int s=0; s<rowsB; ++s) { for(int n=0; n<columnsA; ++n) { vectorsA[n]=MatrixA[r][n]; vectorsB[n]=MatrixB[s][n]; } dist = Routine::HammingDistance(vectorsA, vectorsB); // Calculate Hamming distance if(dist==0) {print << std::endl << "Attractor " << s+1 << " is fixpoint for pattern " << r+1;} else{continue;} } } } // _____________________________________________________________________Und in der main Funktion wird das dann aufgerufen
Routine::MatricesRowComparison(pattern, attractors);(Bei mir heißt die Matrix A pattern und B heißt attractors)
Grüße
-
Ein paar Kommentare dazu:
- Mir gefällt dein Einrückstil nicht. Während vieles davon Geschmackssache ist, ist es doch überwiegender Konsens, dass du sowas wie
if(!(vecA[i]==vecB[i])){hm_distance++;} else{hm_distance=hm_distance+0;}auf mehrere Zeilen aufteilen solltest. Außerdem würde ich auch den Code in Funktionen einrücken. Und Zeilen 29-31 sind falsch eingerückt. Ich persönlich malclang-formatsehr gerne zum automatischen Formatieren (Ich persönlich mag 4 Spaces Einrückung am liebsten). vector::size()liefertsize_tzurück, nichtint. Das ist bei dir durchgehend ignoriert. Sowas wie
int rowsA, columnsA, rowsB, dist; rowsA=MatrixA.size(); columnsA=MatrixA[1].size(); rowsB=MatrixB.size();kannst du besser schreiben wie folgt:
auto rowsA = MatrixA.size(); auto columnsA = MatrixA[1].size(); auto rowsB = MatrixB.size();und das
distkannst du später direkt inauto dist = HammingDistance(...)deklarieren.- Den
ofstreamwürde ich von außen in die Funktion hineingeben, er hat ja mit der eigentlichen Berechnung nix zu tun (wenn es denn wirklich ein stream sein muss und die Funktion nicht vielleicht das Resultat in anderer Form zurückgeben könnte). Undprintklingt eher nah dem Namen einer Funktion als nach einem Stream. Ich würdeosals Namen vorschlagen. - Du solltest Parameter als
constdeklarieren, wenn du sie nicht änderst (Parameter von HammingDistance). - Wozu soll
hm_distance=hm_distance+0;gut sein?! - Den Code habe ich nicht ganz genau durchgeguckt, aber du kopierst 2 Vectoren. Es sollte doch reinen, nur einen Matrix zu transponieren, aus der anderen kannst du die Zeilen doch direkt nehmen.
Und zum Ende: ISLAND VOR!!!!!
- Mir gefällt dein Einrückstil nicht. Während vieles davon Geschmackssache ist, ist es doch überwiegender Konsens, dass du sowas wie
-
Als Beispiel wie man es macht, ist das aber nicht geeignet.
Wenn der else-Zweig keinen Effekt hat (+ 0), dann lass ihn komplett weg.
Die n-Schleife kannst du weglassen,
Ein
dist = Routine::HammingDistance(vectorsA[r], vectorsB[s]);sollte reichen.
-
Danke für die Kritik. Ich werde versuchen sie umzusetzen.
const-correctness ist etwas woran ich derzeit in meinen Büchern lese. Ich muss gestehen ich verstehe bei konkret diesem Punkt noch einiges nicht. Ich sah mir vor kurzem einen Vortrag an, der hat mich ehrlich gesagt aber nur mehr verwirrt. Dieser hier:
https://www.youtube.com/watch?v=Y1KOuFYtTF4
In meinem Buch steht aber auch noch viel das ich noch nicht gelesen habe. Ich bleibe am Ball und hoffe, dass das mit der Zeit und Übung schon wird.
Grüße