Zeichen vergleichen



  • Ja aber wie durchzählen? Angenommen der text ist 8 Felder lang.. Und die zeile die gesucht werden soll 3 felder lang. Dann zähle ich in der ersten Schleife die 8 Felder und muss dann die 3 gesuchten Felder zusammenbauen und dann mit jeweils den nächsten 3 Feldern des Textes vergleichen. Nur ich kann kein statisches if wie im ersten Beispiel mehr bauen wo ich genau wusste das ich drei Felder vergleichen muss.. Wie krieg ich das denn jetzt raus? Die Funktion habe ich ja eingebaut im zweiten Bsp.. getFieldCount..



  • Hint: noch eine schleife.
    Kurt



  • ZuK schrieb:

    Maverick89 schrieb:

    cout <<endl<<"String found on position "<< int(pos-text);
    

    Mir fällt das jetzt schon in mehreren deiner Postings auf dass du nicht castest sondern temporäre Variablen erzeugst. Hat das irgend einen besonderen Grund ?
    Würde das so machen

    cout <<endl<<"String found on position "<< (int)(pos-text);
    

    Kurt

    Der Unterschied ist der, dass der Ausdruck

    int(pos-text)
    

    ein sogenanter static-cast ist und

    (int)(pos-text)
    

    ein C-Cast, bei dem es dem Compiler überlassen bleibt, welchen Cast er durchführt. D.h. hier kann auch ein reinterpret_cast oder ein const_cast geschehen, dem man vielleicht gar nicht will. In so einem Fall würde ein versuchter konkreter static_cast einen Compiler-Fehler verursachen.
    Damit man zur Laufzeit keine bösen Überaschungen erlebt, ist der static_cast immer vorzuziehen. So gesehen ist

    int(pos-text)
    

    der 'bessere' Code. In diesem konkreten Beispiel sollte der Compiler aber in beiden Fällen identischen Code erzeugen.

    Gruß
    Werner



  • Hm.. ok.. jetzt kann ich nicht mehr folgen..
    Die funktion getFieldCount gibt doch einen int zurück.. Zudem geht es mir eher um die Logik des ganzen.. Ich verstehe das mit den zwei Schleifen noch nicht so recht.. Das casten ist erstmal nebensache.. Das ist elfte Klasse Gymnasium Programmieren.. Es geht echt nur um die Logik..

    Hier bin ich schon an der Stelle, denke ich, an der das erste Zeichen aus text mit dem ersten Zeichen aus find übereinstimmt.. Ich komme aber nicht weiter..

    for(int i = 0; i < getFieldCount(text); i++)
    	{
    		for(int x = 0; x < getFieldCount(find); x++)
    		{
    			if(find[x] == text[i])
    			{
    
    			}
    			else
    			{
    				break;
    			}
    		}
    	}
    


  • if(find[x] == text[i+x])
    

    Edit: Natürlich must du schon vor der inneren schleife überprüfen ob das zeichen text[i] mit find[0] übereinstimmt. Nur dann darf die innere schleife laufen.



  • Ok.. Ich glaub ich geb's auf 😉

    Also Code Müsste demnach vor der inneren Schleife so aussehen?

    if(find[0] == text[i])
    

    Leuchtet ein.

    So jetzt sind wir in der inneren Schleife wenn das erste Zeichen von find mit einem beliebigen von text übereinstimmt.. Andernfalls kann es ja keine Übereinstimmung geben..

    Was soll jetzt in der inneren Schleife passieren. Wie kann ich jetzt abfragen ob die n Werte aus find mit den n Werten aus text übereinstimmen?

    Mein Problem ist ganz einfach das ich nicht weiß wie ich in der inneren Schleife überprüfen soll..



  • Würde das ungefähr so machen

    for(int i = 0; i < getFieldCount(text); i++) {
            if ( text[i] == find [0] ) {
               int x;
               for( x = 0; x < getFieldCount(find); x++) {
                  if(find[x] != text[i+x]) // nicht gefunden weiter mit der äusseren schleife
                     break;
               }
               if ( x == getFieldCount(find) ) // gefunden 
                  return true;
            }       
        }
        return false;
    

    Natürlich musst du in der inneren schleife noch überprüfen dass du nicht über das ende von text hinaus zugreifst
    Kurt

    Edit: Logicfehler



  • realmontanakid schrieb:

    Ok.. Ich glaub ich geb's auf 😉

    keine Panik; wir sind bei Dir 🕶

    realmontanakid schrieb:

    Mein Problem ist ganz einfach das ich nicht weiß wie ich in der inneren Schleife überprüfen soll..

    Nun Du musst entscheiden ob alle Zeichen übereinstimmen. Das tut man gemeinhin z.B. so:

    int checkValue        = 0;
    
        int find_len = getFieldCount(find);
        int ende = getFieldCount(text1) - find_len;
        for( int i = 0; i < ende && checkValue == 0; ++i )
        {
            bool gefunden = true;   // mal angenommen wir hätten den Text gefunden
            for( int j = 0; j < find_len && gefunden; ++j )
            {
                if( text1[i+j] != find[j] )  // nein; passt nicht
                    gefunden = false;
            }
            if( gefunden )
            {
                checkValue = 1;
            }
        }
    

    Die Variablen 'find' und 'text1' solltest Du zu std:.string's machen, das ist viel einfacher zu handhaben. In Deinem Original Code

    realmontanakid schrieb:

    int _tmain(int argc, _TCHAR* argv[])
    {
    	char *text1	= new char;
    	char *find	= new char;
    

    hast Du nur Platz für genau ein Zeichen.

    Gruß
    Werner



  • So ich glaub ich hab es... Man man..

    int checkValue		= 0;
    
    	for(int i = 0; i < getFieldCount(text); i++)
    	{
    		if(find[0] == text[i])
    		{
    			for(int x = 0; x < getFieldCount(find); x++)
    			{
    				if(find[x] == text[i+x])
    				{
    					checkValue++;
    				}
    			}
    		}
    		else
    		{
    			continue;
    		}
    	}
    
    	if(checkValue == getFieldCount(find))
    	{
    		cout << "Gefunden" << endl;
    	}
    	else
    	{
    		cout << "Nicht gefunden" << endl;
    	}
    

    Wenn checkValue == getFieldCount von find ist muss er ja die Anzahl an Übereinstimmungen gefunden haben die find selbst als Anzahl Felder hat..

    Vielen Dank für eure Geduld..

    (Soll nich heissen das das der letzte Post war 😉 )

    Gruß



  • realmontanakid schrieb:

    So ich glaub ich hab es...

    Überleg' mal ..
    'text' sei ".....ab....ab...." und 'find' sei "abcd". Dann behaupte ich, dass Dein Algorithmus "Gefunden" ausgibt, da er 4 mal - nämlich 2mal für jeweils 'ab' - den Wert 'checkValue' inkrementiert.

    Zudem greift der Algorithmus auch auf Zeichen zu, die hinter (!) 'text' im Speicher stehen. Das max. erreichbare 'i' ist (Länge von 'text' - 1). Zu diesem 'i' wird in der inneren Schleife noch max. (Länge von 'find' - 1) addiert und das liegt immer außerhalb von 'text'.

    Zum dritten hat Dein Algorithmus O2-Komplexität. Mit jedem Durchlauf von i bestimmst Du in

    for(int i = 0; i < getFieldCount(text); i++)
    

    'getFieldCount' wieder die Länge von 'text'. Das bedeutet, wenn der Algorithmus für 100 Zeichen 1 Sekunde braucht, so brauchst Du bei 1000 Zeichen nicht 10 Sekunden sondern 100s und bei 10000 Zeichen 10000s - also knapp drei Stunden ...
    Speichere das Ergebnis von getFieldCount(text) einfach in einer Variablen - siehe mein letztes Posting.

    Gruß
    Werner



  • Hi

    Ok.. Auch das leuchtet ein..
    Aber eins verstehe ich nicht an dem Code den du gepostet hast nicht..

    int checkValue        = 0; 
    
        int find_len = getFieldCount(find); 
        int ende = getFieldCount(text1) - find_len; 
        for( int i = 0; i < ende && checkValue == 0; ++i ) 
        { 
            bool gefunden = true;   // mal angenommen wir hätten den Text gefunden 
            for( int j = 0; j < find_len && gefunden; ++j ) 
            { 
                if( text1[i+j] != find[j] )  // nein; passt nicht 
                    gefunden = false; 
            } 
            if( gefunden ) 
            { 
                checkValue = 1; 
            } 
        }
    

    if( text1[i+j] != find[j] ) Das ist der Vergleich.. Aber hier wird doch nur ein Zeichen mit einem anderen Zeichen verglichen.. Wenn ich in DiesText sTe suche dann gefunden doch schon true wenn s gefunden wird, oder?



  • bool compareStrings (char * what, char * with)
    {
       for (size_t i=0; i<strlen(with); ++i) {
          if (what[i] != with[i])    // wenn sich ein Zeichen unterscheidet
             return false;           // sind sie verschieden
       }
       return true;                  // sonst gleich
    }
    
    bool contains (chat * str, char * what)
    {
       for (size_t i=0; i<strlen(str) - strlen(what); ++i) {
          if (compareStrings(str + i, what))   // wenn von der i'ten Position aus gesehen die Strings gleich sind
             return true;                      // ist der Text enthalten
       }
       return false;                           // sonst nocht
    }
    


  • if( text1[i+j] != find[j] )  // nein; passt nicht
                    gefunden = false;
    

    realmontanakid schrieb:

    Aber hier wird doch nur ein Zeichen mit einem anderen Zeichen verglichen..

    richtig!

    realmontanakid schrieb:

    Wenn ich in DiesText sTe suche dann gefunden doch schon true wenn s gefunden wird, oder?

    Nicht ganz - 'gefunden' wird false, wenn die Zeichen nicht gleich sind.

    Gruß
    Werner


Anmelden zum Antworten