Laura: Zeichenliste aus zulässigen Zeichen generieren

Hallo,

ich möchte aus einer Liste von Buchstaben, Zahlen und Sonderzeichen eine Liste von Möglichkeiten generieren.

Der erdachte Zeichensatz könnte so aussehen:

$zeichen = array ('1','2','3','4','5','6','7','8','9','0',' ','-','.','ö','ä','ü','ß','&','§','$','%','@','€','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z')  

Ziel ist eine Liste die max 6 Zeichen darstellt und beginnt mit
1
11
12
...
ß
ß1
ß11
ß12
...
zzzzzz

Sofern ich die Dokumentationen richtig verstanden habe muss das ganze dann in einer schleife (while oder foreach) passieren.
Muss ich da jetzt 6 schleifen ineinander bauen? Oder gibt es da eine bessere Lösung ?

Danke

Laura

  1. Hallo Laura,

    ich möchte aus einer Liste von Buchstaben, Zahlen und Sonderzeichen eine Liste von Möglichkeiten generieren.

    warum?

    Der erdachte Zeichensatz könnte so aussehen:

    $zeichen = array ('1','2','3','4','5','6','7','8','9','0',' ','-','.','ö','ä','ü','ß','&','§','$','%','@','€','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z')

      
    
    > Ziel ist eine Liste die max 6 Zeichen darstellt und beginnt mit  
    > 1  
    > 11  
    > 12  
    > ...  
    
    [...]  
    
    > zzzzzz  
      
    die zimlich lang wird. Wenn Du 40 Zeichen hast, dann sind das schon ein paar Milliarden Möglichkeiten :-) Typischerweise prüft man eher, dass ein Testfall die Anforderungen erfüllt.  
      
      
    Freundliche Grüße  
      
    Vinzenz
    
    1. Hallo Vinzenz,

      warum?

      Unsere Techniker in der Firma schreiben für derarige Aufgaben immer unmengen an Stunden auf. Daher möchte ich verstehen was PHP kann (zumindest ansatzweise).
      Also Aufgabe für dieses Wochenende "Grundsätze" von PHP verstehen lernen.

      Mein erster Codeansatz:

      <?php  
      $zeichen = array ('1','2','3','4','5','6','7','8','9','0',' ','-','.','ö','ä','ü','ß','&','§','$','%','@','€','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');  
      $anzahl_zeichen = '48';  
        
      $count_schleife_1 = '0';  
      $count_schleife_2 = '0';  
      while($count_schleife_1 <= $anzahl_zeichen)  
      {  
      	while($count_schleife_2 <= $anzahl_zeichen)  
      		{  
      			echo $count_schleife_1.$count_schleife_2."- ".$zeichen[$count_schleife_1].$zeichen[$count_schleife_2]."<br />";  
      			$count_schleife_2++;  
      		}  
      	$count_schleife_1++;  
      }  
      ?>
      

      Jetzt habe ich vermutlich noch einen Versändnisfehler. Denn der Zeichensatz wir nun nicht bis zz angezeigt sondern bis 048- 1z.
      Also habe ich (vermutlich) ein Problem ist der ersten schleife oder?

      1. Fehler gefunden den 0 Count umgestetzt.

        <?php  
        $zeichen = array ('1','2','3','4','5','6','7','8','9','0',' ','-','.','ö','ä','ü','ß','&','§','$','%','@','€','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');  
        $anzahl_zeichen = '48';  
          
        $count_schleife_1 = '0';  
        while($count_schleife_1 <= $anzahl_zeichen)  
        {  
        	$count_schleife_2 = '0';  
        	while($count_schleife_2 <= $anzahl_zeichen)  
        		{  
        			echo $count_schleife_1.$count_schleife_2."- ".$zeichen[$count_schleife_1].$zeichen[$count_schleife_2]."<br />";  
        			$count_schleife_2++;  
        		}  
        	$count_schleife_1++;  
        }  
        ?>
        
      2. Hallo,

        Also Aufgabe für dieses Wochenende "Grundsätze" von PHP verstehen lernen.

        da hast du dir aber ein anspruchsvolles Ziel gesetzt. ;-)

        $zeichen = array ('1','2','3','4','5','6','7','8','9','0',' ','-','.','ö','ä','ü','ß','&','§','$','%','@','€','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
        $anzahl_zeichen = '48';

        Ich zähle 49 Zeichen. Und man muss sie nicht von Hand abzählen, dafür bietet PHP die Funktion count().
        Übrigens ist das ein reiner Zahlenwert, warum sollte man das also in Anführungszeichen notieren?

        $count_schleife_1 = '0';
        $count_schleife_2 = '0';

        Dito: Warum Zahlenwerte in Anführungszeichen?

        while($count_schleife_1 <= $anzahl_zeichen)

        Durch die Endebedingung mit "kleiner oder gleich" hast du den Zählfehler am Anfang (48 statt 49) vermutlich unbewusst kompensiert.
        Für so einen Anwendungsfall ist übrigens die for-Schleife ideal geeignet, weil sie die Initialisierung der Zählvariablen, die Überprüfung der Endebedingung und das Hochzählen übersichtlich und logisch an einer Stelle zusammenfasst:

        ~~~php for ($count_schleife_1=0; $count_schleife_1<$anzahl_zeichen; $count_schleife_1++)
           { // Schleifenrumpf
           }

          
        So long,  
         Martin  
        
        -- 
        Das einzige Problem beim Nichtstun: Man weiß nie, wann man damit fertig ist.  
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        
      3. Hallo Laura,

        Unsere Techniker in der Firma schreiben für derarige Aufgaben immer unmengen an Stunden auf.

        Du solltest bereits gelernt haben, dass das verschiedene Gründe hat, die man beim fertigen "Produkt" nicht auf Anhieb sieht:

        Zunächst muss man Überlegungen anstellen, wie man das Ziel erreichen kann. Du hast gelernt, dass man prüfen muss, ob das "Produkt" richtig funktioniert (was oftmals nicht auf Anhieb der Fall ist), anschließend Fehler verbessern, ...

        Das kostet alles Zeit, die Du selbst in den paar resultierenden Zeilen Code nicht siehst.

        Das, was Du jetzt hast, funktioniert für zwei Stellen. Verbessern könntest Du es mit Martins Anmerkungen. Für dreibuchstabige Listen müsstest Du neuen Code schreiben. Es ist zwar nicht schwer, den vorhandenen Code anzupassen, aber wie Du selbst in Deinem Ausgangsbeitrag angemerkt hat, kann es ja nicht sein, dass Du für jede Anzahl von Stellen eine eigene Funktion schreibst. Also ist die derzeitige Lösung noch suboptimal und für die "Produktion" ungeeignet.

        Eine elegante und flexible Lösung kannst Du mit selbstaufrufenden Funktionen schaffen:

        Übergib einer Funktion die bisher ermittelte Zeichenkette, die Länge der Restzeichenkette und den Zeichenvorrat, aus dem die Zeichen zu nehmen sind:

        Wenn die Länge der Restzeichenkette größer ist als 0
            Für jedes Zeichen aus dem Zeichenvorrat
                Hänge an die bisher ermittelte Zeichenkette das aktuelle Zeichen an
                Die Länge der Restzeichenkette verringere um 1
                Rufe die Funktion mit diesen modifizierten Werten erneut auf
            Ende Für
        Sonst
            Restzeichenkettenlänge ist Null: gib die Zeichenkette aus
        Ende Wenn

        oder in PHP:

        function print_all_strings($string, $length, $zeichenvorrat) {  
          # Muss noch etwas angehängt werden?  
          if($length > 0) {  
            # Ja  
            # hänge systematisch alle Zeichen aus dem Zeichenvorrat an  
            foreach ($zeichenvorrat as $zeichen) {  
                # rufe die Funktion mit  
        	print_all_strings(  
                  # angehängtem Zeichen  
                  $string . $zeichen,  
                  # einer um 1 kleineren Restlänge  
                  $length - 1,  
                  # und dem immer noch gleichen Zeichenvorrat erneut auf  
                  $zeichenvorrat);  
            }  
          }  
          else {  
            # Nein, die Zeichenkette ist fertig zusammengebaut  
            # Gib sie aus  
            echo $string, "<br>\n";  
          }  
        }
        

        Beispielaufruf für Deine Aufgabenstellung:

        $zeichen = array ('1','2','3','4','5','6','7','8','9','0',' ','-','.','ö','ä','ü','ß','&','§','$','%','@','€','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');  
          
        # Alle Zeichenketten der Längen von 1 bis 6  
        for($length = 1; $length <= 6; $length++) {  
           # Start mit einer leeren Zeichenkette,  
           # der entsprechenden Maximallänge  
           # und Deinem Zeichenvorrat  
           print_all_strings('', $length, $zeichen);  
           # viel Spass beim Durchrattern der Milliarden Möglichkeiten :-)  
        }  
        
        

        Und ja: so einen Ansatz schüttelst Du Dir nicht einfach so aus dem Ärmel.
        Da die Rekursionstiefe hier durch die Länge beschränkt ist, ist der zusätzliche Speicherplatzverbrauch durch die Rekursion übrigens vernachlässigbar.

        Freundliche Grüße

        Vinzenz

        1. Hallo Ingrid,

          Du hast etwas Wichtiges vergessen: kontextgerechte Behandlung

          function print_all_strings($string, $length, $zeichenvorrat) {

          # Muss noch etwas angehängt werden?
            if($length > 0) {
              # Ja
              # hänge systematisch alle Zeichen aus dem Zeichenvorrat an
              foreach ($zeichenvorrat as $zeichen) {
                  # rufe die Funktion mit
          print_all_strings(
                    # angehängtem Zeichen
                    $string . $zeichen,
                    # einer um 1 kleineren Restlänge
                    $length - 1,
                    # und dem immer noch gleichen Zeichenvorrat erneut auf
                    $zeichenvorrat);
              }
            }
            else {
              # Nein, die Zeichenkette ist fertig zusammengebaut
              # Gib sie aus

          # Behandle sie für den Kontext HTML

          echo htmlspecialchars($string), "<br>\n";
            }
          }

            
            
          Freundliche Grüße  
            
          Vinzenz
          
  2. Hello Laura,#

    ich möchte aus einer Liste von Buchstaben, Zahlen und Sonderzeichen eine Liste von Möglichkeiten generieren.

    Der erdachte Zeichensatz könnte so aussehen:

    $zeichen = array ('1','2','3','4','5','6','7','8','9','0',' ','-','.','ö','ä','ü','ß','&','§','$','%','@','€','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z')

      
    
    > Ziel ist eine Liste die max 6 Zeichen darstellt und beginnt mit  
    > 1  
    > 11  
    > 12  
    > ...  
    > ß  
    > ß1  
    > ß11  
    > ß12  
    > ...  
    > zzzzzz  
    >   
    > Sofern ich die Dokumentationen richtig verstanden habe muss das ganze dann in einer schleife (while oder foreach) passieren.  
    > Muss ich da jetzt 6 schleifen ineinander bauen? Oder gibt es da eine bessere Lösung ?  
      
    Sollen die Länge des erzeugten Strings und seine Elemente zufällig sein, oder müsse die irgendwelchen Regeln genügen, außer der Maximallänge?  
      
    Da Du die Zeichen bereits in einem Array hast, könntest Du die Shuffle-Funktion benutzten.  
    <http://de.php.net/manual/en/function.shuffle.php>  
      
      
    ## Stelle einen leeren Ergebnisstring zur Verfügung  
    $ergebnis = '';  
      
    ## Würfele eine Zufallszahl für die Länge aus  
    $len = zufall();   ## Die richtige Funktion suchst Du Dir bitte aus dem PHP-Handbuch :-)  
      
    ## Nimm diese Zufallszahl für eine dedizierte Schleife  
      
    for($i = 0; $i < $len; $i++)  
    {  
        ## bringe das Array durcheinander (den Elementen werden neue Keys zugeordnet)  
        shuffle($zeichen);  
      
        ## hänge das erste Element des Arrays an den Ergebnisstring an  
        $ergebnis .= $zeichen[0];  
    }  
      
      
    Diese Vorgehensweise ermöglicht die von dir geforderten "zzzzzz", also mehrfaches Auftreten eines Zeichens im String.  
      
      
      
      
      
    Liebe Grüße aus dem schönen Oberharz  
      
      
    Tom vom Berg  
    ![](http://selfhtml.bitworks.de/Virencheck.gif)  
      
    
    -- 
     ☻\_  
    /▌  
    / \ Nur selber lernen macht schlau  
    <http://bergpost.annerschbarrich.de>
    
    1. Hallo Tom,

      vielen Dank. Shuffel habe ich mir gerade angesehen. Da ich aber eine logische Reihenfolge ohne Dopplungen haben möchte bleibt mir wohl nur die schleifenvariante:
      http://forum.de.selfhtml.org/?t=208543&m=1418287

      Sonnt müsste man ja immer im fertigen Array suchen ob es die generierte Reichenfolge schon gibt und das dann wieder sortieren.

      Danke Laura