std::sort und Lambda Funktion
-
Hallo,
ich hab eine Vektor aus pairsvector<pair<string, string>> morsezeichen;
und möchte diesen Vektor sortieren
void Morse::toSort() { sort(morsezeichen.begin(), morsezeichen.end(), sortHelper); }
und um die Reihenfolge festzulegen habe ich eine separate Funktion (ist keine Lambda Funktion, ich weiß)
bool Morse::sortHelper(pair<string, string>& left, pair<string, string>&right) { return morsecode_counter(left.second) > morsecode_counter(right.second); }
Die Funktion morsecode_counter rechnet irgendeinen Wert aus. Nun bekomme ich aber als Fehlermeldung:
Fehler 3 error C3867: "Morse::sortHelper": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&Morse::sortHelper", um einen Zeiger auf den Member zu erstellen.
und
Fehler 4 error C2780: 'void std::sort(_RanIt,_RanIt)': Erwartet 2 Argumente - 3 unterstützt
Irgendjemand eine Idee wie man das richtig macht? Ich hab in einer anderen Aufgabe das prinzipiell auch so gemacht, das ich als drittes Argument für std::sort einfach den Namen der entsprechenden Funktion hingeschrieben habe (auch ohne Argumentliste, auch wenns von der Sintax her etwas seltsam aussieht).
mfg
-
Warum ist die Funktion eine Memberfunktion? Mach eine freie Funktion draus und schon gehts.
-
Welche Funktion meinst du? Es sind alles Memberfunktionen der Klasse Morse.
-
vivess schrieb:
Welche Funktion meinst du? Es sind alles Memberfunktionen der Klasse Morse.
Lass mal sehen - vielleicht genau die eine, zu der der Compiler die Fehlermeldungen ausspuckt?
-
vivess schrieb:
vector<pair<string, string>> morsezeichen;
Ist das wirklich so eine gute Idee? Möchtest du wirklich gleich alle Strings plus die kodierten Strings bereitstellen? Warum sollte man diese in dem Fall außerdem sortieren?
Ich würde einfach eine passende std::map definieren:std::map<char, const char*> mymap;
bzw.
std::map<char, std::string> mymap;
Und dann die map im Konstruktor aufbauen:
mymap['a'] = ".-"; ...
Mit deren Hilfe können anschließend strings sehr einfach kodiert werden. Wenn die Ausgabe naheliegenderweise über Lautsprecher erfolgen soll, reicht es auch, über den String zu iterieren und zeichenweise kodieren+ausgeben (siehe dafür auch tolower aus <cctype>).
-
Hmm also ich hab es jetzt mit einer multimap gemacht, aber in den nächsten aufgabe bekomm ich dann probleme.
Die Aufgabe war ja, dass wir eine textdatei haben in der die morsecodes und ihre bedeutung aufgelistet sind
0 - - - - - 9 - - - - . 8 - - - . . 7 - - . . . 6 - . . . . 5 . . . . . etc.
(Zeichen für das der Morsecode steht und dann Morsecode selber)
Wir sollten dann die Morsecodes ausrechnen, d.h. '-' = 3 Einheiten, '.' und Leerzeichen = 1 Einheit. Dann sollten wir die Textdatei nach den Einheiten der Morsecodes sortiert ausgeben. Also in der Form
1 . E 3 - T 3 . . I 5 . . . S 5 . - A 5 - . N etc.
Länge des Morsecodes - Morsecode - Bedeutung des Morsecodes
Also erst die morsecodes die nur kurz dauern, und dann die langen etc.Ich hab dann so ein Gebilde benutzt
multimap<int, pair<string, string>> morsecodes;
(Länge des Morsecodes, und dann ein pair von Morsecode und Zeichen wofür der Morsecdoe steht)
Das funktioniert nun auch so weit, also der gibt das alles richtig aus und ich muss das Teil nun auch nicht separat sortieren weil multimap ja von sich aus nach Schlüsseln aufsteigend sortiert.
Das Problem ist nun das ich in der nächsten Aufgabe einen Text in Morse codieren soll, und da hilft mir die multimap ja reichlich wenig mehr. Ich könnte natürlich für die zweite Aufgabe wieder die Textdatei mit den morsecodes in so eine map einlesen
map <char, string> mc
aber das wirkt auf mich etwas unelegant weil dann die multimap die ich vorher erstellt habe ja dann nur eine Funktion erfüllt und ntürlich auch speicher frisst.
-
vivess schrieb:
aber das wirkt auf mich etwas unelegant weil dann die multimap die ich vorher erstellt habe ja dann nur eine Funktion erfüllt und ntürlich auch speicher frisst.
Na und? Dann mach eben nicht alle Aufgabenteile in der gleichen Funktion, wenn dich das so stört. Das ist wahrscheinlich sowieso eine gute Idee.
Ich finde den Ansatz mit der Multimap allgemein nicht so gelungen, außer du hast später noch einmal Bedarf für diese "Länge". Ich würde eine map<string, char> machen, mit einem Sortierkriterium, das vor einem normalen, lexikalischen Stringvergleich zuerst nach der "Länge" guckt. Dann hast du es schön symmetrisch, eine map<string, char> und eine map <char, string>. Wenn du es besonders schön machen möchtest, kombinierst du die beiden noch zu einer Klasse bidirectional_map.
Der Tipp ist natürlich nur dann sinnvoll, wenn du später noch Bedarf für eine Übersetzung von Morse nach Text hast. Ich spekuliere mal, dass dies gewiss einer der späteren Aufgabenteile sein wird.
-
Also ich hab es jetzt auch mit einer map<string, char> und map<char, string> gemacht. Und ja ich muss nun einen Morsecode in Text übersetzen. Das Problem ist jetzt, ich habe dann ja so einen Morsecode
- . . . - . . . . - - - . . . . - - - . .
Das heißt nach jedem Zeichen 3 Leerzeichen und nach jedem Wort 10 Leerzeichen.
Wie Frage ist nun, wie bekomm ich nun z.b. den ersten Morsecode
- . .
aus der Textdatei herausgezogen und in einen string gespeichert? Zwischen jedem Zeichen ist ja ein Leerzeichen, d.h.
-(leerzeichen).(leerzeichen).
Deswegen würde es ja so mit getline nicht funktionieren
getline(Morsecode, morsecode, ' ')
Hat irgendjemand eine Idee?
-
Du musst halt nach 3 bzw. 10 Leerzeichen suchen. Du kannst es dir wahrscheinlich einfacher machen, indem du zuerst alle alleinstehenden Leerzeichen ganz entfernst.
-
Wie mach ich das? Sowas funktioniert ja nicht
getline(Morsecode, morsecode, " ");
weil getline als Begrenzer wohl nur ein einzelnes zeichen kann und nicht mehrere.
Und alle alleinstehenden strings zu löschen weiß ich auch nicht wie das geht, weil das hier zum beispiel
atcoded.erase(remove(atcoded.begin(), atcoded.end(), ' '), atcoded.end());
Alle leerzeichen herauslöscht. Also dann ist alles aneinandergedatscht.