Position des ersten Zeichens ausgeben



  • Ich hab hier einen Fehler, den ich nicht nachvollziehen kann.

    #include <stdio.h>
    
    #define SIZE 20
    
    char any(char s1[], char s2[]);
    
    int main()
    { 
      char eingabe1[SIZE],eingabe2[SIZE]; 
    
      int x,y; 
    
      /* Die Forschleife geht alle Positionen im Array durch, damit auch kein Wert
      schon am Anfang des Programmstarts darin vorhanden ist */
      for(x=0; x <= (SIZE-1); x++)
      {
        eingabe1[x] = ' ';
        eingabe2[x] = ' '; 
      } 
    
      printf("Eingabe 1:\n"); 
      gets(eingabe1); 
    
      printf("Eingabe 2:\n");
      gets(eingabe2);
    
      /* y ist die Hochzählvariable für Eingabe1 (Zeile 1) und x ist die Hochzählvariable
      für Eingabe2 (Zeile 2). Der Wert der neuen Zeile wird in eingabe1[y] gespeichert */
      for(x=0;x<=(SIZE-1);x++)
      { 
        for(y=0;y<=(SIZE-1);y++) 
        { 
          eingabe1[y] = any(eingabe1[y],eingabe2[x]);
        }
      }
    
            return 0;
    }
    
    /* any: erste Position in s1 wo irgendein Zeichen aus s2 vorkommt */
    char any(char s1[], char s2[])
    {
      int i,j;
      for (i = 0; s1[i] != '\0'; i++)
        for(j = 0; s2[j] != '\0'; j++)
          if(s1[i] == s2[j])
            return i;
      return -1;
    }
    

    Dazu muss gesagt werden, dass die Ausgabe des Wertes noch fehlt.
    Aufgabe für dieses Programm: Schreiben sie eine Funktion, die die Position des ersten Zeichens in der Zeichenkette s1 liefert, das in der Zeichenkette s2 vorkommt. Enthält s1 kein Zeichen aus s2, so soll der Resultatwert -1 sein.
    - info: Die Bibliotheksfunktion strbrk macht dasselbe, liefert aber einen Zeiger auf die Stelle.



  • /* y ist die Hochzählvariable für Eingabe1 (Zeile 1) und x ist die Hochzählvariable
      für Eingabe2 (Zeile 2). Der Wert der neuen Zeile wird in eingabe1[y] gespeichert */
      for(x=0;x<=(SIZE-1);x++)
      { 
        for(y=0;y<=(SIZE-1);y++) 
        { 
          eingabe1[y] = any(eingabe1[y],eingabe2[x]);
        }
      }
    

    Das Stück ist doch völlig unnötig. Du brauchst doch die Funktion nur einmal aufzurufen.

    int nRet;
    
    nRet = any(eingabe1, eingabe2);
    
    printf("Das Ergebnis ist %d\n", nRet);
    


  • ah danke für den Tipp.... ich hab gleich eine Variante, die funktioniert.... dauert nur noch einen Moment, weil ich noch schnell den Kram kommentieren will.



  • #include <stdio.h>
    
    #define SIZE 20
    int any(char s1[], char s2[]);
    
    int main()
    { 
      char eingabe1[SIZE],eingabe2[SIZE]; 
    
      int x,y, Ergebnis;
    
      /* Die Forschleife geht alle Positionen im Array durch, damit auch kein Wert
      schon am Anfang des Programmstarts darin vorhanden ist */
      for(x=0; x <= (SIZE-1); x++)
      {
        eingabe1[x] = ' ';
        eingabe2[x] = ' '; 
      } 
    
      printf("Eingabe 1:\n"); 
      gets(eingabe1); 
    
      printf("Eingabe 2:\n");
      gets(eingabe2);
    
      /* Ergebnis wird ermittelt aus den Werten der Eingabe1 und Eingabe2. Die Funktion
      bearbeitet beide Eingabezeilen und gibt am Ende einen Integerert aus */
      Ergebnis = any(eingabe1,eingabe2);
      printf("Das Ergebnis ist %d\n", Ergebnis);
    return 0;
    }
    
    /* any: erste Position in s1 wo irgendein Zeichen aus s2 vorkommt */
    int any(char s1[], char s2[])
    {
      int i,j;
      /* "i" ist die Hochzählvariable für die erste Eingabezeile. "j" ist die
      Hochzählvariable für die zweite Eingabezeile. In beiden For-Schleifen wird
      kontrolliert, ob man das Zeichenende erreicht hat.
      Die If-Schleife kontrolliert Zeile 1 auf Zeile 2 und gibt bei Übereinsstimmung
      eines Zeichens, den Wert der Position zurück. Falls keine Übereinstimmung eines
      Zeichens vorhanden ist, dann wird nur -1 zurückgegeben. */
      for (i = 0; s1[i] != '\0'; i++)
        for(j = 0; s2[j] != '\0'; j++)
          if(s1[i] == s2[j])
            return i+1;
      return -1;
    }
    

    Das ist das Programm, welches auch funktioniert... 😉

    Habt ihr Verbesserungen oder seht ihr noch irgendwelche Fehler, die man austüfteln könnte ? 😕



  • Du könntest main ans Ende verschieben, dann kannst du dir auch die Deklaration von any sparen.
    Deine Implementation ist schon ok so. Ich könnte mir aber vorstellen, dass mit einer Art Map, die Funktion ein besseres Laufzeitverhalten hat. Dh, du hast ein Array, das für alle möglichen Zeichen ein Flag erfassen kann. Dann läufst du s2 einmal durch und für jedes Zeichen, das du findest, setzt du entsprechendes Flag auf 1, alle anderen auf 0. Dann läufst du einmal s1 durch und schaust, ob für das aktuelle Zeichen das Flag gesetzt ist.

    btw:
    Der Standard kennt kein strbrk, was du hier nachbaust, ist strcspn.



  • In wie weit wäre das Laufzeitverhalten denn besser als vorher ? 😕



  • @chillbert
    Eine Verbesserung wäre es z. B. schon, wenn du Zeiger verwendest, anstatt deinen Indexvariablen (so wie ich es im anderen Thread schon vorgeschlagen habe).

    Das Initialiseren deiner Eingabevariablen mit Leerzeichen kannst du dir auch sparen.

    Und anstatt gets() solltest du unbedingt fgets() verwenden! Das ist das wichtigste was du ändern musst. Du kannst ja jetzt mal testen was so alles passiert, wenn du mehr als 20 Zeichen eingibst, z. B. 50 pro Eingabe. Wenn du Glück hast, passiert gar nichts, aber irgendwann krachts.



  • Ich nehm mal an, dass mir das Programm dann um die Ohren fliegen wird.

    *g*



  • cHillb3rT schrieb:

    Ich nehm mal an, dass mir das Programm dann um die Ohren fliegen wird.

    *g*

    Das nicht gerade :), aber du bekommst wahrscheinlich ne tolle Fehlermeldung vom OS, dass du auf Speicher zugreifst, der dir (dem Programm) nicht gehört. Das Programm stürzt dabei natürlich ab bzw. wird einfach beendet vom OS.



  • Hör nicht auf groovemaster. Es ist blödsinn, da es überhaupt keinen sichtbaren Geschwindigkeitsvorteil bei deinen Miniprogr. bringen würde,
    Dein Algo hat einen worst case von n² und zwar wenn kein Element vom zweiten Array im ersten Array vorkommt. Da deine Problematik zu den Suchalgo gehört, könnte man für grössere Datenmenge Hashing Algorithmen O(n) oder Suchbäume(O(log n)) einsetzen.
    Da dies aber für dein kleines Bsp. völlig übertrieben wäre, solltest du dir den Aufwand sparen. Aus rein Interessengründen kann ich es dir empfehlen dich mal näher mit der Thematik auseinander zusetzen.



  • Also reserviert fgets() automatisch Speicher, damit ich nicht irgendeinen Speicher, der vielleicht von anderen Programmen genutzt wird, nehme.

    Aber dann ist meine Frage wiederum. Wenn ich jetzt genau weiß, dass ich nur so viel Zeichen im Programm eingeben darf, dann ist doch meine Variante sinnvoller oder ? 😕



  • groovemaster schrieb:

    Du könntest main ans Ende verschieben, dann kannst du dir auch die Deklaration von any sparen.
    Deine Implementation ist schon ok so. Ich könnte mir aber vorstellen, dass mit einer Art Map, die Funktion ein besseres Laufzeitverhalten hat. Dh, du hast ein Array, das für alle möglichen Zeichen ein Flag erfassen kann. Dann läufst du s2 einmal durch und für jedes Zeichen, das du findest, setzt du entsprechendes Flag auf 1, alle anderen auf 0. Dann läufst du einmal s1 durch und schaust, ob für das aktuelle Zeichen das Flag gesetzt ist.

    btw:
    Der Standard kennt kein strbrk, was du hier nachbaust, ist strcspn.

    Du solltest schonmal lesen was die any fkt. macht, bevor du antwortest. und sie bildet bestimmt kein strcspn nach. 2 Solltesr du dich erkundigen, da es im Standard strcspn und strspn gibt die unterschiedl. Dinge erledigen. Du solltest auch bei deiner Besserwisserei nicht ganz so bürokratisch sein, da cHillbr3t bestimmt die flt. strpbrk die im Std. definiert ist.

    Cu



  • cHillb3rT schrieb:

    Also reserviert fgets() automatisch Speicher, damit ich nicht irgendeinen Speicher, der vielleicht von anderen Programmen genutzt wird, nehme.

    Aber dann ist meine Frage wiederum. Wenn ich jetzt genau weiß, dass ich nur so viel Zeichen im Programm eingeben darf, dann ist doch meine Variante sinnvoller oder ? 😕

    Nein fgets() reserviert dafür nicht noch extra Speicher, es schreibt einfach nicht mehr Zeichen als angegeben an den übergebenen Speicherbereich.

    Nein deine Variante ist nicht sinnvoller. Du weißt zwar wieviele Zeichen du eingeben darfst, aber der gemeine Benutzer (auch DAU genannt ;)) weiß das nicht (und auch wenn du es hinschreibst, gibts immer wieder Dümmste Anzunehmende User, die das nicht beachten). Du darfst dabei also nicht wie ein vernünftiger Programmierer denken, sondern musst von einem absoluten Laien ausgehen. Es darf also gar nicht die Möglichkeit bestehen, dass so ein grober Fehler auftreten kann.



  • Dann geh ich generell von dem netten DAU aus 😛

    Aber jetzt hab ich eigentlich keine Fragen mehr zum Programm. Es leuchtet mir alles ein in dieser Hinsicht. 👍

    THX an alle !!!



  • cHillb3rT schrieb:

    In wie weit wäre das Laufzeitverhalten denn besser als vorher ?

    Überleg mal, wie oft deine Zeichenketten im besten und schlimmsten Fall durchlaufen werden, und wie oft bei meinem Vorschlag.

    AJ schrieb:

    Eine Verbesserung wäre es z. B. schon, wenn du Zeiger verwendest, anstatt deinen Indexvariablen

    Bei einem gut optimierenden Compiler sollte das eigentlich keine Unterschiede ausmachen.

    grenouille_unreg schrieb:

    Hör nicht auf groovemaster. Es ist blödsinn, da es überhaupt keinen sichtbaren Geschwindigkeitsvorteil bei deinen Miniprogr. bringen würde

    Wer hat denn von Geschwindigkeitsvorteil gesprochen? Offensichtlich nur du.

    grenouille_unreg schrieb:

    Da deine Problematik zu den Suchalgo gehört, könnte man für grössere Datenmenge Hashing Algorithmen O(n) oder Suchbäume(O(log n)) einsetzen.
    Da dies aber für dein kleines Bsp. völlig übertrieben wäre

    Was mein Vorschlag keineswegs ist und sehr einfach zu realisieren ist. Ich hab ja auch gesagt, dass cHillb3rT's Lösung ok ist und wollte nur Anregungen für andere Möglichkeiten geben.

    grenouille_unreg schrieb:

    Du solltest schonmal lesen was die any fkt. macht, bevor du antwortest.

    Das solltest du eigentlich.

    grenouille_unreg schrieb:

    und sie bildet bestimmt kein strcspn nach

    Doch, das tut sie.

    grenouille_unreg schrieb:

    Du solltest auch bei deiner Besserwisserei nicht ganz so bürokratisch sein, da cHillbr3t bestimmt die flt. strpbrk die im Std. definiert ist.

    Offensichtlich hast du ein Problem. Aber solche plumpen Trollversuche von Unregs nehm ich sowieso nicht ernst. Wenn ich besserwisserisch wäre, hätte ich dich darauf hingewiesen, dass

    grenouille_unreg schrieb:

    unterschiedl.

    eine super Abkürzung für unterschiedliche ist. 😉
    strpbrk macht zwar im Grunde das gleiche wie strcspn, der Rückgabewert von any passt aber besser zu strcspn.



  • groovemaster schrieb:

    Bei einem gut optimierenden Compiler sollte das eigentlich keine Unterschiede ausmachen.

    Ich würde mich nicht immer auf die Optimierungsfähigkeiten des Compilers verlassen. Es ist in dem Fall zwar total irrelevant (auch wenn es der Compiler nicht wie vielleicht gewünscht optimiert), aber bei größeren Sachen sollte man auf jeden Fall darauf achten, "optimiert" zu programmieren und wenn man es sich schon bei den kleinen Sachen angewöhnt, dann muss man sich nicht bei größeren Sachen umgewöhnen.


Anmelden zum Antworten