"Stringfunktionen" nachbauen



  • Das ist schon besser. Du kannst dir aber die Abfrage if(g>0) sparen. Es funktioniert leider immer noch nicht ganz richtig. Geh mal folgendes durch:

    strfind("xabcxyz", "xyz");
    

    Als Rückgabe wird eigentlich 4 erwartet. Es kommt aber 0 zurück.

    Und bei diesem Aufruf:

    strfine("xyzabc", "xyz");
    

    wird -1 zurückgegeben.



  • So, hier finde ich keinen Fehler mehr:

    #include <stdio.h>
    
    int str_find(char *string, char *pattern) {
    	int g = 0;
    	int h = -1;
    	int i = 0;
    
    	for(i = 0; i < strlen(string); i++) {
    		if(string[i] == pattern[g]) {
    			g++;
    
    			if(strlen(pattern) == g) {
    				if(h == -1) {
    					h = i - strlen(pattern) + 1;
    				}
    
    				break;
    			}
    		}
    		else {
    			g = 0;
    		}
    	}
    
    	if(g == strlen(pattern)) {
    		return h;
    	}
    	else {
    		return -1;
    	}
    }
    

    🙂



  • Du hast da

    ...
    int i = 0;
    
    for(i = 0; ...)...
    

    Mach die deklaration von i doch direkt in der Schleife:

    for(int i = 0;...)...
    

    oder lass bei der ersten das "= 0" weg.

    Code-Hacker



  • Code-Hacker schrieb:

    Du hast da

    ...
    int i = 0;
    
    for(i = 0; ...)...
    

    Mach die deklaration von i doch direkt in der Schleife:

    for(int i = 0;...)...
    

    oder lass bei der ersten das "= 0" weg.

    Code-Hacker

    Ja, wenn du C++ als Sprache nutzt ist das möglich. In C kann man nur zu Anfang eines Blockes Variablen deklarieren.

    Gruß Tobias



  • tobidope schrieb:

    Code-Hacker schrieb:

    Du hast da

    ...
    int i = 0;
    
    for(i = 0; ...)...
    

    Mach die deklaration von i doch direkt in der Schleife:

    for(int i = 0;...)...
    

    oder lass bei der ersten das "= 0" weg.

    Code-Hacker

    Ja, wenn du C++ als Sprache nutzt ist das möglich. In C kann man nur zu Anfang eines Blockes Variablen deklarieren.

    In C99 ist so eine Schleife vollkommen legal.



  • Die Funktion ist noch nicht fehlerfrei:

    str_find("gegeben","geben") liefert -1 statt 2



  • Also ich würde auch die Definition in der Schleife weglassen

    @chrisi
    Hmmm ich kann den Fehler nicht entdecken

    @testy
    Jetzt könntest du noch auf die Performance schauen.
    Du hast zwei überflüssige Abfragen drin und du könntest ein paar strlen() einsparen bzw. anders anordnen.



  • Hm, also optimiert habe ich das ganze schon ein wenig. Nun sieht es so aus:

    #include <stdio.h>
    
    int str_find(char * string, char * pattern) {
    	int g = -1;
    	int h = 0;
    	int i = 0;
    	int j = 0;
    
    	for(i = 0; i < strlen(string); i++) {
    		if(string[i] == pattern[h]) {
    			h++;
    
    			if((j = strlen(pattern)) == h) {
    				if(g == -1) {
    					g = i - j + 1;
    				}
    
    				return g;
    			}
    		}
    		else {
    			h = 0;
    		}
    	}
    
    	return -1;
    }
    

    Jedoch finde ich den Fehler nicht, auf den Chrisi_K angesprochen hat.



  • Gut und wenn du nun (j = strlen(pattern)) noch vor die Schleife setzt und das strlen() bei der Bedingung der Schleife noch rauskriegst, dann wär ich zufrieden 😃

    Im nächsten Schritt könntest du dir noch überlegen, wie man das ganze mit Zeigern lösen könnte. 😋



  • Du vergleichst string[0] mit pattern[0]: stimmt überein
    Dann vergleichst Du string[1] mit pattern[1]: stimmt auch
    Dann vergleichst Du string[2] mit pattern[2]: passt nicht
    Du machst weiter mit string[3] mit pattern[0]: Fehler, die Übereinstimmung von string[2] und pattern[0] wurde nicht gefunden

    Mein Vorschlag (ungetestet, nicht optimiert):

    int str_find(char * string, char * pattern) { 
        int i, j; 
    
        for(i = 0; i < strlen(string); i++) { 
            if(string[i] == pattern[0]) { 
                 for(j = 1; j < strlen(pattern); j++) {
                     if(string[i+j] != pattern[j]) break;
                 }
                 if(j==strlen(pattern)) return i;
            } 
        } 
    
        return -1; 
    }
    


  • Oh, stimmt. Also muss beim else-Zweig noch ne Abfrage rein.



  • So, es sieht nun so aus:

    int strfind(char * string, char * pattern) {
    	int i, j, k, l;
    
    	k = strlen(pattern);
    	l = strlen(string);
    
    	for(i = 0; i < l; i++) {
    		if(string[i] == pattern[0]) {
    
    			for(j = 1; j < k; j++) {
    
    				if(string[i + j] != pattern[j]) {
    					break;
    				}
    			}
    
    			if(j == k) {
    				return i;
    			}
    		}
    	}
    
    	return -1;
    }
    

    Es funktioniert wunderbar 🙂 Nach deren Vorbild habe ich mich an die strrfind() gemacht, die bis auf eine Kleinigkeit auch schon recht gut zu funktionieren scheint:

    int strrfind(char * string, char * pattern) {
    	int i, j, k, l;
    
    	k = strlen(pattern);
    	l = strlen(string);
    
    	for(i = l; i > 0; i--) {
    		if(string[i - 1] == pattern[k - 1]) {
    
    			for(j = (k - 2); j > 0; j--) {
    
    				if(string[i - 1 - j] != pattern[j]) {
    					break;
    				}
    			}
    
    			if(j == 0) {
    				return i - k;
    			}
    		}
    	}
    
    	return -1;
    }
    

    Wenn ich nun in einem String "bla und bla" nach "bla" suche, klappt es wunderbar. Suche ich jedoch in "bla und blala" gibt er mir statt 8 eine 10 zurück. Warum?



  • also wenn du den leuten ein gefallen tuen willst benutze den buchstaben l nicht für ein variablen bezeichner

    achja mit pointer finde ich das leichter

    int strfind(char * string, char * pattern)
    {
        char * p = pattern;
        char * s = string;
        do
        {
            if(*s++ == *p++)
            {
                if(!*p)
                    return s - string;
            }
            else
            {
                p = pattern;
            }
        }while(*s);
        return -1;
    }
    


  • int scopy(char **dest, char *src, int start = 0, int end = 0);
    int scopycat(char **dest, char *src, int start = 0, int end = 0);
    int scopyins(char **dest, char *src, int pos = 0, int start = 0, int end = 0);
    

    Diese String-Funktionen könnten durchaus hilfreich sein.......

    int scopy(char **dest, char *src, int start, int end)
    {
    	int i = 0;
    
    	if(start > end)
    		start = end;
    	if( src )
    	{
    		if(( strlen(src) >= end ) || ( strlen(src) < start ))
    		{
    			if(( start == 0 ) && ( end == 0 ))
    			{
    				*dest = (char*)realloc( *dest, sizeof(char) * strlen(src) + 1 );
    				for( i = 0; i <= strlen(src); i++)
    					(*dest)[i] = src[i];
    			}
    			else if( start == end )
    			{
    				*dest = (char*)realloc( *dest, sizeof(char) * 2 );
    				(*dest)[0] = src[end - 1];
    				(*dest)[1] = '\0';
    			}
    			else 
    			{
    				*dest = (char*)realloc(*dest, sizeof(char) * (end - start + 2)); 
    				int size = _msize(*dest);	
    				for(i = 0; i < (end-start+1); i++)
    					(*dest)[i] = src[i + start-1];
    				(*dest)[i] = '\0';
    			}
    			return 1;
    		}
    		else return 0;
    	}
    	else return 0;
    }
    
    int scopycat(char **dest, char *src, int start, int end)
    {
    	char	*tmp1	= NULL, 
    			*tmp2	= NULL;
    	int		i		= 0, 
    			len		= 0;
    
    	if(*dest)
    	{
    		len = strlen(*dest);						//ohne 0-zeichen
    		tmp1 = (char*)malloc(sizeof(char) * len);
    		for( i = 0; i < len; i++)
    			tmp1[i] = (*dest)[i];
    		if(scopy( &tmp2, src, start, end ))
    		{
    			*dest = (char*)realloc(*dest, sizeof(char) * (len + strlen(tmp2) + 1 ));
    
    			for(i = 0; i < len; i++)
    				(*dest)[i] = tmp1[i];
    
    			for(i = 0; i < strlen(tmp2) + 1; i++)
    				(*dest)[i + len] = tmp2[i];
    
    			free(tmp1);
    			free(tmp2);
    
    			return 1;
    		}
    		else
    		{
    			free(tmp1);
    			return 0;
    		}
    	}
    	else return scopy(dest, src, start, end);
    }
    

    hab ich kürzlich geschrieben.................
    gibt noch verbesserte Versionen und Erweiterungen davon....

    ...



  • @Dimah
    Keine schlechte Lösung, aber was passiert, wenn ich folgendes übergebe (der Sinn bleibt mal dahingestellt ;)):

    strfind("","xyz");
    


  • int strfind(char *string,char *pattern)
    {
       int j,k=strlen(pattern);
       for(int i=0;i<strlen(string)-k+1;i++)
       {
          j=0;
          while(j<k&&string[i+j]==pattern[j]) j++;
          if(j==k) return i;
       }
       return -1;
    }
    


  • AJ schrieb:

    @Dimah
    Keine schlechte Lösung, aber was passiert, wenn ich folgendes übergebe

    einfach die do{}while in eine while() schleife aendern und alles sollte passen.

    @_Stefan:
    du musst jetzt nur noch deine version etwas optimieren.

    irgendwie merkt man, das dimah C++ programmiert
    seine loesung ist kurz und die der c programmierer lang 🙂



  • @shade
    Ich glaube eher man merkt, wer hier schon mit Zeigern programmiert hat und wer nicht 😉


Anmelden zum Antworten