Kommentar entfernen Funktion



  • Seht ihr Verbesserungspotentital ? Zeitkomplexität worst case=(n²] , Speicherkomplexität konstant .

    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    
    void removeComment(char* str)
    {
    	int length,i,j;
    	for(i=0,j=0;str[j];i++,j++)
    	{
    
    		if(str[j] == '/' && str[j+1] == '*')
    		{
    			while( !(str[j] == '*' && str[j+1] == '/'))
    			{
    				j++;
    			}
    			j +=2;
    		}
    
    		str[i] = str[j];
    
    	}
    
    	str[i]=0;
    }
    
    int main()
    {
    
    	char str[] = "Aber hallo/*Das ist ein Kommentar*/ ich gehe morgen/*Ein Kommentar*/ ins Kino";
    
    	removeComment(str);
    
    	cout<<str;
    
    }
    

  • Mod

    Unbenutzte Variable: length.
    stdio.h ist cstdio in C++. du nutzt sowieso nichts aus diesem Header.
    Deine Zeitkomplexität ist tatsächlich O(n).

    Dein Algorithmus ist falsch. Probier mal:

    char str[] = "Aber hallo/*Das ist ein Kommentar*//* dies auch*/ ich gehe morgen/*Ein Kommentar*/ ins Kino";
    

    oder

    char str[] = "Aber hallo/*Das ist ein Kommentar am Ende*/";
    

    oder

    char str[] = "Aber hallo/*Das ist ein Kommentar ohne Ende";
    

    Während Nummer 1 und Nummer 3 offensichtliche Fehler produzieren sollten, ist der Fehler beim zweiten eventuell zu subtil, um bei einem einfachen Testlauf wahrgenommen zu werden. Denk am besten selber mal durch, was da wohl passieren könnte. Oder nutz einen Debugger. Eventuell läuft auch Nummer 3 ohne Fehler durch, aber es sollte leicht nachvollziehbar sein, wieso dieses Beispiel trotzdem fehlerhaftes Verhalten erzeugen kann.

    Allgemein wär's natürlich schicker, wenn das auf string statt auf nicht-const char-Arrays liefe; oder noch viel besser: Auf beliebigen Zeichensequenzen. Vermutlich ist das aber noch ein bisschen zu hoch für dich. Sieh es als Bemerkung für die Zukunft.



  • ja (2) verursacht keinen Fehler aber er hat halt dann 2 Nullterminierungen 🙂

    Fall 1 ist klar ein Fehler.

    Den Algo kann man sicher einfacher gestalten. Aber ist schon schwer.



  • Fall 2 ist kein Problem da werden halt 2 Nullterminierungen geschrieben.

    Und das hier sollte Fall 3 lösen

    if(str[j] == '/' && str[j+1] == '*')
    		{
    			while(str[j+1]!= 0 && !(str[j] == '*' && str[j+1] == '/' ))
    			{
    				j++;
    			}
    			if(str[j+1] != 0)
    				j +=2;
    			else
    				j++;
    		}
    
    }
    

    Allgemein glaub ich ist die Implementierung noch etwas umständlich.


  • Mod

    XX schrieb:

    ja (2) verursacht keinen Fehler aber er hat halt dann 2 Nullterminierungen 🙂

    Das war nicht, was ich meinte. Achte auf die Abbruchbedingung der for-Schleife in Zeile 9. Welchen Wert hat j, wenn diese geprüft wird?

    Allgemein glaub ich ist die Implementierung noch etwas umständlich.

    So ist es. Ich würde erst einmal eine Implementierung machen, die mit ein paar Flags und Zählern arbeitet: In Kommentar, J/N? Letztes Zeichen war ein * oder / (je nachdem, ob wir gerade im Kommentar sind oder nicht), J/N? Wie viele Zeichen haben wir schon kopiert? Dann einfach durchlaufen bis Ende ('\0') und wenn wir außerhalb eines Kommentars sind, Zeichen kopieren. Dabei anhand der Flags feststellen, wann wir von Kommentar zu nicht-Kommentar wechseln und umgekehrt. Danach kann man weiter schauen, ob man noch was eleganteres finden kann.



  • Sowas kann man ganz einfach mit einem Zustandsautomaten lösen.

    void removeComment(char* str)
    {
      enum {
        state_0,
        state_cbegin,
        state_comment,
        state_cend
      } state = state_0;
    
      char* target = str;
      for (const char* p = str; *p; ++p)
      {
        switch (state)
        {
          case state_0:
            if (*p == '/')
              state = state_cbegin;
            else
              *target++ = *p;
            break;
    
          case state_cbegin:
            if (*p == '*')
              state = state_comment;
            else if (*p == '/')
            {
              *target++ = '/';
            }
            else
            {
              *target++ = '/';
              *target++ = *p;
              state == state_0;
            }
            break;
    
          case state_comment:
            if (*p == '*')
              state = state_cend;
            break;
    
          case state_cend:
            if (*p == '/')
              state = state_0;
            else if (*p == '*')
              ;
            else
              state = state_comment;
            break;
        }
      }
    
      *target = '\0';
    
      if (state != state_0)
        throw std::runtime_error("incomplete comment");
    }
    


  • < Oder damit



  • RegEx schrieb:

    < Oder damit

    Das ist ein Zustandsautomat.



  • otze schrieb:

    Das ist ein Zustandsautomat.

    Dann ist es natürlich absolut equivalent.


Log in to reply