regulärer Ausdruck mit sed gesucht



  • Hallo,

    ich sitze hier gerade an einer Aufgabe von unserem Professor, die ich einfach nicht packe zu lösen. Folgende Aufgabenstellung ergibt sich hier:

    // +---------------------------------------------------------------------------
    // + main - liest fehlerkontrolliert und "endlos" zeilenweise von der
    // + Standardeingabe ein, ersetzt in jeder Zeile alle Zeichenketten, die
    // + dem Muster ".*a" entsprechen durch die Zeichenkette "$$" und gibt die
    // + bearbeitete Zeile auf der Standardausgabe als eigene Zeile aus -
    // + entsprechend obigem sed-Befehl
    // +---------------------------------------------------------------------------

    mein Code, den ich bisher aufgeschrieben habe lautet wie folgt:

    #include <iostream>
    #include <cstddef>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        string s("");
    
        while(getline(cin,s))
        {
           string t("");
           size_t pos_anf(s.size());
    
           for(size_t i(0); i < s.size(); ++i)
           {
              if(s[i+1] == 'a')
              {
                 t += "$$";
                 i = s.size();
              }
              else
              {
                  t += s[i];
              }
           }
           cout << t << endl;
        }
    
        if(!cin.eof())
        {
           cerr << endl << "##Fehler!" << endl;
        }
    
        system("Pause");
        return 0;   
    }
    

    Der Professor hat ein Benotungstool für uns angelegt und mit diesem Code habe ich immernoch eine 5. Der Fehler ist hier, dass zbsp. der String "abca" mit $$ ausgegeben wird, jedoch darf das nicht passieren!

    Folgende Ausdrücke hat der Professor in seinem Benotungstool zum testen hinterlegt!

    BCD ab ef a$b a b ababb Abab

    keine Ersetzung hier

    ababb und Abab wird aber in meinem Code durch $$ ersetzt. Wie kann ich das schreiben, dass das nicht mehr passiert?

    Es wäre auch super, wenn ihr mir vielleicht auch eine Erklärung mitliefert, falls ihr graviernde Änderungen vornehmt.

    vielen Dank
    gruß bigbootykilla



  • Also ich verstehe das nicht ganz. Ist gemeint, dass die GESAMTE Zeile dem Muster ".*a" entsprechen soll? Falls ja brauchst du eigentlich nur nachzusehen ob der letzte Buchstabe ein a ist und falls dem so ist die gesamte Zeile durch "$$" ersetzen.

    Falls das nicht gemeint ist weiß ich nicht warum bei den Beispielen nichts ersetzt wird. Eigentlich sollte jedes a und alle Zeichen davor immer ersetzt werden:

    BCD -> BCD
    ab -> $$b
    ef -> ef
    a$b -> $$$b
    a -> $$
    b -> b
    ababb -> $$bb
    Abab -> $$b

    😕

    MfG SideWinder


  • Mod

    Mit ".*a" meinst du alles, was mit einem Punkt anfängt und irgendwann ein 'a' kommst, oder? Falls ja, wäre es vielleicht ein Anfang, mal nach Punkten, statt nach 'a's zu suchen.

    edit: Da SideWinder die Aufgabe ebenfalls nicht versteht, wäre es vielleicht mal ein Anfang wenn du den genannten sed-Befehl zeigst und am Besten noch ein Beispiel.



  • .*a ist das Muster für Zeichenketten die mit einem a enden und davor eine beliebige Anzahl Buchstaben haben, oder keinen Buchstaben vor a.

    Nach dem a dürfen keine weiteren Zeichen mehr kommen
    Demzufolge sollte nur das einzeln stehende a in dem Beispiel ersetzt werden.

    Ich vermute dass nicht die ganze Zeile gegen das Muster getestet werden soll, sondern jeder Teilstring.



  • Mit ".*a" meinst du alles, was mit einem Punkt anfängt und irgendwann ein 'a' kommst, oder?

    Nein nicht das Zeichen ".*" ist damit gemeint, sondern alle Buchstaben, die vor einem a kommen können. zbsp. qwertzaaaaaa! Da sollen die "aaaaaa" mit $$ ersetzt werden. Bisher habe ich nur eine Beispielaufgabe mit einer 1 gelöst bekommen.

    Hier hat es sich auch um SED gehandelt. Die Aufgabenstellung lautete:

    // +---------------------------------------------------------------------------
    // + main - liest fehlerkontrolliert und "endlos" zeilenweise von der
    // + Standardeingabe ein, ersetzt in jeder Zeile alle Zeichenketten, die
    // + dem Muster "[56][78].*" entsprechen durch die Zeichenkette "@@@@" und
    // + gibt die bearbeitete Zeile auf der Standardausgabe als eigene Zeile
    // + aus.
    // + 2007/11/01, ????
    // +---------------------------------------------------------------------------

    Der Code, der mir schlussendlich die Note 1 dazu lieferte lautete:

    int main() {
      // --- Ihr Code hier:
    string s("");
    
    while (getline(cin,s)){
    string t("");
    
    size_t idxanf(s.size());
    for (size_t i(0); i<s.size(); ++i) {
    
    if ((s[i] == '5' || s[i] == '6') && (s[i+1] == '7' || s[i+1] == '8') ) { 
    
    t+="@@@@";
    i=s.size();
    
    }else{
    t+=s[i];
    }
    
    }
    
    cout << t << endl;
    }
    if(!cin.eof()){
    cerr << "Fehler" << endl; return 1;
    }
    
      return 0;
    }
    

    Ich hoffe der Code mit [56][78].* hilft euch ein wenig! Hier wurde einfach der Befehl: sed 's/[56][78].*/@@@@/g' programmiert!



  • Nichts für ungut, aber wenn das ne Note 1 gibt, dann muss ich leider sagen, dass dein Prof bzw. dein Lehrer schlechte Augen hat.

    Zeile 9 ist unnötig, du benutzt idxanf ja nirgends.
    Wenn beispielsweise s 5 Zeichen lang ist, wird i die Werte [0,4] annehmen, aber innerhalb der Schleife würdest du auf s[5] zugreifen -> schlecht.

    Du überprüfst zwar, ob eine Kombination von
    57
    58
    67 oder
    68
    vorkommt, aber nicht ob die beiden Ziffern am Anfang eines Teilstrings vorkommen.
    Du wertest eine komplette Zeile als mögliche Zeichenkette aus. Vermutlich sollen aber die Teilstrings überprüft werden. Momentan wird nur das erste Vorkommen einer der obigen Kombinationen ersetzt, danach weist du i ja sofort den Wert s.size() zu und beendest damit die Schleife.

    Meiner Meinung nach wurde die Aufgabenstellung also nur teilweise erfüllt, aber umso besser für dich wenn das trotzdem ne 1 gibt 😃



  • hehe.... an der Stelle von idxanf kommt ja auch eine Compilerwarnung, aber anschließend kompiliert er mir trotzdem die Datei und wenn ich das Benotungstool durchlaufen lass, zeigt mir das Benotungstool eine 1 an, aber ich weiß auch, dass der Prof uns immer gesagt hat, dass keine Fehler da sein dürfen, aber es ist ja kein Fehler sondern nur eine Warnung.

    Wie würdest du es denn anders machen?

    (Wenn es euch was helfen würde, um das alles mal zu sehen, kann ich das Paket gerne mal komplett hochladen, aber ich weiß nicht ob es von nöten ist! Dort steht ja lediglich für uns, wie wir die Noten während wir programmieren herausfinden können!)

    Und des weiteren such ich immernoch die Lösung für die obige Aufgabe .*a

    Ich finde das gerade schon ein abartiges Niveau, da wir erst in der 4.Vorlesung in c++ sind und unser Prof alle 2 Wochen ein Testat schreibt. Daher sind die Aufgaben relativ klein (themenbezogen) und geben eine 1. Ich will garned dem seine Abschlussprüfung sehen, bei dem kranken Zeugs, was der da abfrägt! 😃

    lg bigbootykilla


Anmelden zum Antworten