Bewerbungstest (Backend (Server)) C++ Basics



  • Hallo erstmal. Es geht um vollgendes. Vor einiger Zeit habe ich mich bei einer Firma auf eine Lehrstelle als Fachinformatiker für Anwendungsentliklung beworben. Nun bin ich zur Zeit ohnehin im Stress und habe heute ne email dieser Firma erhalten der ein Test beigefügt ist, der binnen der nächsten 5 Werktage möglichst gelöst zurückgeschickt werden soll. Nunja, ich selbst habe noch nicht die Zeit dazu gehabt mich ernsthaft mit c++ auseinander zu setzen, deshalb bräuchte ich dringen Hilfe 🙂

    Aufgabe ist folgende:

    1. Ziel „Wortsortierer“
    Alle Worte eines Textes sollen aus einer Textdatei eingelesen
    und alle Buchstaben in Kleinbuchstaben verwandelt werden.
    Danach sollen die Worte sortiert und wieder ausgegeben werden.
    Interpunktionen und Zahlen werden dabei ignoriert. Die
    Ausgabe soll dabei nach den beiden Anfangsbuchstaben der
    Worte gruppiert werden. Innerhalb dieser Gruppen erfolgt die
    Ausgabe in umgekehrter alphanumerischer Reihenfolge. Doppelte
    Worte werden nur einmal mit der Häufigkeit ihres Auftretens
    ausgegeben.
    2. Verlauf
    Dem Programm wird die einzulesende Datei übergeben. Danach
    liest das Programm die Datei ein, sortiert die Worte und
    gibt die Liste direkt auf den Bildschirm aus.
    3. Abgabe
    Das Programm soll in C++ geschrieben werden. Andere Programmiersprachen
    werden nicht anerkannt.
    4. Abzugeben sind
    - fertig kompiliertes Programm
    - kommentierter Source-Code
    - kurze Beschreibung des Programms mit Ablaufprotokoll

    Schon seit längerem plane ich mich eingehender mit c++ auseinander zu setzen bin aber noch nicht dazu gekommen. Es soll weißgott nicht so ausgelegt werden, als sei ich zu faul die Arbeit selbst zu machen, nur schaff ichs momentan nicht mir die Basics selbst beizubringen.

    Was ich mir von dem Threat erhoffe, sind konstruktive Lösungsansätze (tut so als ob ihr es einem Unwissenden erklärt, damit ich es auch auf jedenfall verstehe^^), Ein bisschen Basiswissen, was man halt zum bewältigen der Aufgabe gebraucht wird.

    Ich würde mich riesig über jede hilfe freuen, werde mich auch selbst noch ein bissl da hinnein fuchsen, danke zunächst allen die sich die mühe gemacht haben meinen ellenlangen Text zu entziffern und erwägen mir beizustehen. 🙂

    Vielen Dank


  • Mod

    Erstmal ein nützlicher Link zu einer Klassenreferenz:

    http://www.cplusplus.com/reference/

    Was du brauchst sind die Streamklassen für die Eingabe/Ausgabe. Zur Speicherung der Worte aus der Datei bietet sich jeweils die Stringklasse an. Da viele Worte im Speicher haben willst, brauchst du irgendeine Datenstruktur. Die vordefinierte Containerklasse "vector" sollte zu deinem Problem passen. Zur Verarbeitung der Daten könntest du entweder die fertigen Algortithmen aus der STL nehmen oder einen eigenen entwerfen. Wenn ich deinen Ausbildungsstand richtig einschätze, ist es wohl besser, du schreibst einen eigenen Algorithmus. Die Verwendung der Standardalgorithmen ist zwar sehr elegant, aber es wäre etwas was man noch zusätzlich lernen müsste und deine Zeit ist ja anscheinend knapp. Das du einen Sortieralgortihmus schreiben kannst, setze ich dabei mal voraus, ansonsten musst du dir eben auch noch die Algorithmenbibliothek angucken.

    Abgesehen von der Referenz die ich oben angegeben habe, noch folgende Tipps: Die Ein-/Ausgabe vom und zum Bildschirm wird in jedem C++ Anfängerbuch gleich am Anfang behandelt. Die Benutzung der fstreams zur Datei Ein-/Ausgabe geht ziemlich analog.
    Zur Stringklasse gibt es eigentlich nicht viel zu sagen, außer dass sie schönerweise schon Vergleichoperatoren vordefiniert hat, was das Sortieren einfacher macht, sei es mit den Standardalgorithmen oder von Hand. Für das Konvertieren in Kleinbuchstaben wirst du wohl selbst was schreiben müssen.
    Für die Verwendung der Vectorklasse musst du dich mit Templates auseinandersetzen, was für Anfänger nicht ganz einfach ist. Mit dem Anschauen von ein paar Beispielen und ein bisschen Herumspielen sollte es aber machbar sein, zumindest etwas funktionierendes hinzubekommen, auch wenn vieleicht nicht ganz klar wird, was da passiert.



  • SeppJ schrieb:

    Für das Konvertieren in Kleinbuchstaben wirst du wohl selbst was schreiben müssen.

    Was nicht all zu schwierig ist:

    //main.cpp
    #include <iostream>
    #include <string>
    #include <cctype> // tolower(char)
    using std::cout;
    using std::endl;
    using std::string;
    
    int main()
    {
    	string s("KLEIN");
    	// Wandelt jeden Großbuchstaben eines Strings in einen Kleinbuchstaben um
    	for(string::size_type index = 0; index != s.size(); ++index)
    		s[index] = tolower(s[index]);
    	// Ausgabe des veränderten Strings
    	cout << s << endl;
    
    	return 0;
    }
    

    knusperkekz schrieb:

    ...nur schaff ichs momentan nicht mir die Basics selbst beizubringen.

    Ohne ein paar Grundlagen, glaube ich kaum das du das in nur 5 Werktagen schaffen wirst. Neben SeppJs Tipps würde ich dir raten, dir vielleicht auf die schnelle noch ein C++-Buch wie z. B. "C++ Primer" zuzulegen und dort die entsprechenden Abschnitte zu lesen um die Aufgabe damit dann zu lösen.

    Edit zur späten Stunde: Nachdem ich mich jetzt selber mal an deiner Aufgabe versucht habe, würde ich dir doch eher zu einer std::map anstatt zu einem std::vector raten, da sich mit einer std::map sowohl das zählen, als auch das sortieren der eingelesenen Wörter viel leichter realisieren lässt und nicht zuletzt auch deshalb, weil es ja in der Aufgabe heißt das mehrfach auftauchende Wörter am Ende nur einmal ausgegeben werden sollen :).



  • Hast du schon Vorkenntnisse im Programmieren? Was kannst du schon alles bzw. was hast du schon gemacht?
    Ansonsten musst du dich 5 Tage wirklich konsequent vollzeit auf den Arsch setzen und etwas tun, sonst ist das auf keinen Fall lösbar. Sorry, dass nicht gerade hoffnungsvoll klingt, aber das ist denke ich ehrlich.

    Jemanden zu finden, der dir das Programm schreibt oder nötige Schnippsel gibt, ist wohl kein Problem. Dadurch hast du aber nichts gewonnen. Denn Du bist der jenige, der im Gespräch erklären können muss, was du da gemacht hast. Und du bist auch der jenige, der - je nach dem wie professionell das Programm gemacht ist - sich mit den Erwartungen konfrontiert sieht, wenn du aufgrund des Programms eingestellt wirst.

    Im Übrigen finde ich es schon ein wenig dreist, jemanden, der Anwendungsentwickler lernen will, mit so einer Aufgabe zu konfrontieren. Klingt ein wenig danach, als wenn dort eine billige Arbeitskraft gesucht wird.

    Um aber nicht nur zu labern 😉 Das fertige Programm könnte sich wohl im Rahmen eines 10-Zeilers bewegen, wenn man schon gut gefestige C++-Kenntnisse hat.

    Für eine Lösung solltest du Dir folgende Konzepte sowie Klassen aus der C++ Standard Bibliothek anschauen und verstehen und erklären können was sie machen (wie sie es machen, braucht dich für den Anfang nicht zu interessieren, das solltest du abstrakt betrachten):

    Die Parameterübergabe an ein C++-Programm mit argc und argv
    std::ifstream (aus <fstream>)
    std::cout (aus <iostream>)
    std::string ( aus <string>)
    tolower (aus <cctype>)
    std::map (aus <map>)
    Iteratoren. In Verbindung mit std::map deren reverse-Iteratoren.

    Such dir Beispiele dazu und schreib dir kleine Testprogramme, um alles für sich mal auszuprobieren, bevor du es in das Gesamt-Programm einbaust. Bei Fragen frag ruhig wieder. Denk aber daran, dass du wirklich nichts davon hast, wenn dir das Programm auf dem Goldteller serviert wird. Zumal die entsprechende Firma vielleicht sogar dieses Forum hier kennt. 😉



  • 7H3 N4C3R schrieb:

    std::map (aus <map>)
    Iteratoren. In Verbindung mit std::map deren reverse-Iteratoren.

    Ich hab die Aufgabenstellung jetzt nicht seziert, aber std::set (für den OT: <set>) klingt meiner Meinung nach für diesen Fall nach der besseren Alternative.



  • Hättest du sollen. 😉 Die Anzahl der mehrfachen Vorkommen soll gezählt werden.



  • Oh pardon, ja habs auch grad nochmal gelesen 🤡



  • 7H3 N4C3R schrieb:

    Das fertige Programm könnte sich wohl im Rahmen eines 10-Zeilers bewegen, wenn man schon gut gefestige C++-Kenntnisse hat.

    Hu, inklusive meiner zum Teil recht ausschweifenden Kommentare und den Using-Deklarationen komme ich mit meiner Lösung auf genau 142 Codezeilen. Offenbar mach ich irgendwas falsch 😮.



  • Hab jetzt 40 gebraucht, mit Leerzeilen. Allein 7 Zeilen für die Includes und 9 für die toLower-Funktion.

    Würd's dir ja per PN schicken, wenn das aktiviert wäre. 😉



  • 35 mit allem drum und dran. ToLower ist in 2 Zeilen aber die doofe Vergleichsfunktion alleine schluckt schon 10 Zeilen. Bekomm aber gerad' 'nen Knoten im Gehirn beim Versuch die zu ändern. Und das "ignorieren" von Sonderzeichen etc. habe ich einfach mal wörtlich genommen.



  • 40 Zeilen und 35 Zeilen sind echt verdammt kurz 👍. Hmmm... ich werde vielleicht mal noch ein bisschen an meinem Code herumschrauben :). Meine Funktion zur Umwandlung in Kleinbuchstaben ist 6 Zeilen lang (ohne Kommentare und ohne die Deklaration der Funktion mitzuzählen).

    Fellhuhn schrieb:

    Und das "ignorieren" von Sonderzeichen etc. habe ich einfach mal wörtlich genommen.

    Ich habe es so gemacht, das ich alle Sonderzeichen und Zahlen einfach aus den Strings lösche (mit einer 11 Zeilen langen Funktion, auch wieder ohne Kommentare und ohne die Deklaration der Funktion mitzuzählen) bevor sie in die std::map geschrieben werden :D.

    Wenn ich die Kommentare alle nicht mitzählen würde, wäre mein Code zwar auf jeden Fall auch kürzer als 142 Zeilen, aber ich glaube von 40 Zeilen bzw. 35 Zeilen bin ich noch ein paar Zeilen entfernt :).

    Edit: Was ich noch vergessen habe: Includes habe ich für meine oben erwähnten Funktionen auch nicht mitgezählt.



  • Mit Filterung komm ich auf 40. Etwas doof das die ganzen alten C-Funktionen immer einen int wollen und keinen char...

    EDIT: 45. Vergessen das durch simples Entfernen von Sonderzeichen ja Wörter zusammengelegt werden...



  • ohne includes und die Implementation der Funktionen zum Filtern von Zeichen und "verkleinern" der Buchstaben bin ich mit Kommentar- und leerzeilen bei 36 gelandet - lässt sich bestimmt noch quetschen 😉

    bool isNumber(std::string);
    std::string filter(std::string); //löscht Interpunktionszeichen und ändert alles auf Kleinbuchstaben
    
    typedef std::multiset<std::string> Strset;
    typedef Strset::iterator StrIter;
    
    int main()
    {
      ifstream input("input.txt");
      std::string s;
      Strset strings;
      while (input >> s)
      { 
        s = filter(s);
        if (!isNumber(s)) 
          strings.insert(s);
      } 
    
      StrIter first = strings.begin(), end = strings.end();
      while (first != end)
      {
        struct Cmp12 //vergleicht die ersten beiden Buchstaben zweier strings
        { 
          bool operator() (std::string lhs, std::string rhs) 
          { return (lhs[0]==rhs[0]) && (lhs[1]==rhs[1]); }
        }
        //range = Gruppierung nach Anfangsbuchstaben
        std::pair<StrIter> range = std::equal_range(first, end, *first, Cmp12());
        StrIter it = first = range.second;
        while (it != range.first)
        {
          unsigned int equals = it - std::find(range.first, it, *(it-1));
          std::cout << equals << "faches Vorkommen von " << *(it -= equals) << std::endl;
        }
      }
    }
    


  • 25 Zeilen, alles mitgezählt. Schön ist das aber nicht...



  • MFK schrieb:

    25 Zeilen, alles mitgezählt. Schön ist das aber nicht...

    Auch alle Sonderfälle? Sonderzeichen entfernt, dadurch keine Wörter zusammengelegt. Wörter die vorher nur durch ein Sonderzeichen getrennt waren werden danach als einzelne Wörter gewertet etc.?
    Diese Kleinigkeiten blähen den Code meist auf. 🙂

    43 ohne extremes Gestauche.



  • Also, wenn ich meinen Code so Zähle wie wie es pumuckl getan hat (ohne Inlcudes und ohne Funktionsimplemetierung) und ich außerdem noch alle Kommentare rauspfeffere dann komme ich auf 55 Codezeilen, wobei ich keine Algorithmen der STL verwende (was unter anderem auch daran liegt, das ich std::equal_range bisher noch gar nicht kannte 😉 )
    Übrigens geht meine main() so los:

    int main(int argc, char *argv[])
    {
    	if(argc != 2) {
    		cerr << "Falsche Anzahl an uebergebenen Argumenten." << endl;
    		warten();
    		return EXIT_FAILURE;
    	}
    /* ... */
    

    da bei mir der Dateiname der zu lesenden Datei mittels der Befehlszeile des Programms übergeben wird. ( warten() verhindert nur das sich das Konsolenfenster gleich wieder schließt 😉 )

    Fellhuhn schrieb:

    Wörter die vorher nur durch ein Sonderzeichen getrennt waren werden danach als einzelne Wörter gewertet etc.?

    Das habe ich bei meinem Code aber auch nicht berücksichtigt, was dazu führt, das bei mir aus 2, durch Sonderzeichen getrennte Wörter einfach ein Wort wird. Da besteht wohl auch noch Nachbesserungsbedarf bei mir :D.

    An den Threadersteller: Hast du dich eigentlich schon an der Aufgabe probiert? Und falls ja, hast du sie vielleicht schon gelöst? Wenn nicht dann immer her mit deinen konkreten Fragen, wir helfen ja gerne :).



  • 23 🤡 (Ohne Inkludes, ohne Leerzeilen, ohne Kommentare, ohne alleinstehende geschweifte Klammern, mit Body der Hilfsfunktionen)



  • eine.
    Mit allen Hilfsfunktionen und Kommentaren, allerdings ohne includes, ohne Zeilenumbrüche zwischen Befehlen, Blöcken etc. Und vor allem ohne Lesbarkeit 🤡



  • Ich finds ja schon interessant, wie aus dem Problem ein Wettbewerb um den kürzesten Code entstanden ist. 😃

    @ pumuckl:
    Gerade wollte ich vorschlagen, dass der Wettbewerb nun nach dem Kriterium "wenigste Zeichen im Code" fortgeführt werden könnte. 😉



  • pumuckl schrieb:

    eine.
    Mit allen Hilfsfunktionen und Kommentaren, allerdings ohne includes, ohne Zeilenumbrüche zwischen Befehlen, Blöcken etc. Und vor allem ohne Lesbarkeit 🤡

    Schummler :p


Log in to reply