• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Buchstabenreihenfolge eines Wortes ändern?

root3450

Mitglied
Hallo ich würde gerne mit PHP die Buchstabenreihenfolge eines Wortes ändern: Vorher: Lesezeichen Nachher: Leczseiehen Wichtig dabei ist, dass der erste und letzte Buchstabe gleich seien soll. Einen Lösungsansatz habe ich schon: ich muss die Länge des Wortes mit strlen herausfinden und mit substr den ersten und den letzten Buchstaben in eine andere Variable schreiben. Wie kann ich die Buchstaben "bunt durcheinander Würfeln"? Vielen Dank im Voraus :)
 
Werbung:
Das wäre eine ganz nette Aufgabe für PHP-Golf.

PHP:
function f($word)
{
    $a = str_split($word);

    $first = array_shift($a);
    $last  = array_pop($a);
    shuffle($a);

    return $first . implode('', $a) . $last;
}

error_reporting(-1);
ini_set('display_errors', 1);

$tests = array(
    '',
    'L',
    'Ln',
    'Len',
    'Lesezeichen'
);

echo "<pre>\n";

foreach ($tests as $test) {
    printf("Test: %-15s => %-15s\n", $test, f($test));
}

str_split für Unicode vielleicht hier: http://de2.php.net/manual/en/function.str-split.php#107658
 
Werbung:
@mermshaus:

Was noch fehlt, wäre eine Prüfung ob der String leer ist. Soweit wie ich das sehe würde str_split dann FALSE zurückliefern und ich glaube nicht dass array_shift und array_pop damit etwas anfangen können. Im Übrigen - Den Umweg über str_split könnte man sich sparen. Das wäre auch legitim:

PHP:
<?php
    $str = 'This is a test.';
    $first = $str[0];
?>
 
Was noch fehlt, wäre eine Prüfung ob der String leer ist. Soweit wie ich das sehe würde str_split dann FALSE zurückliefern und ich glaube nicht dass array_shift und array_pop damit etwas anfangen können.

Das siehst du falsch. Wenn der an str_split übergebene String leer ist (oder allgemein: kürzer als der zweite optionale Parameter split_length, sofern dieser >0 ist), wird ein Array zurückgegeben, das als einziges Element den gesamten String enthält.

PHP:
<?php

var_dump(str_split(''));

// array(1) {
//   [0]=>
//   string(0) ""
// }

Schau dir außerdem mal den ersten Testeintrag in meinem Code an.

Im Übrigen - Den Umweg über str_split könnte man sich sparen. Das wäre auch legitim:

PHP:
<?php
    $str = 'This is a test.';
    $first = $str[0];
?>

Überleg dir lieber noch mal in Ruhe, was mein Code genau tut (der Aufruf von shuffle zum Beispiel).

* * *​

Hier noch eine „sauberere“ UTF-8-Variante.

PHP:
<?php

/**
 *
 * @param  string $word
 * @return string
 * @throws Exception
 */
function f2($word)
{
    // Da PHP schwach typisiert ist, könnte $word so ziemlich alles enthalten.
    if (!is_string($word)) {
        throw new Exception(sprintf(
                'Function "%s": Parameter "%s" must be of type "%s"',
                __FUNCTION__, 'word', 'string'));
    }

    // Die UTF-8-Variante von str_split.
    $a = preg_split('//u', $word, -1, PREG_SPLIT_NO_EMPTY);

    // Sicherstellen, dass die beiden Variablen in jedem Fall initialisiert
    // sind.
    $first = '';
    $last  = '';

    // Das Array muss mindestens zwei Elemente haben, damit vorne und hinten
    // eins entfernt werden kann. In diesem Fall *müssen* die beiden Elemente
    // jedoch auch entfernt werden, da shuffle sie sonst in die falsche
    // Reihenfolge bringen könnte "ab" => "ba". Bei einem leeren Array oder
    // einem mit einem Element kann shuffle dagegen keine Reihenfolge ändern.
    if (count($a) > 1) {
        $first = array_shift($a);
        $last  = array_pop($a);
    }

    // Der "Rumpf" des Worts (z. B. "esezeiche") wird durchgemischt.
    shuffle($a);

    // Alles wieder zusammenkleben.
    return $first . implode('', $a) . $last;
}



error_reporting(-1);
ini_set('display_errors', 1);

$tests = array(
    '',
    'L',
    'Ln',
    'Len',
    'Lesezeichen'
);



echo "<pre>\n";

foreach ($tests as $test) {
    printf("Test: %-15s => %-15s\n", $test, f2($test));
}

// Fehler künstlich provozieren.
f2(new stdClass());

Hinweis: Es ist nicht sichergestellt, dass der auf diese Weise erzeugte String, ungleich dem Eingabestring ist.

Zudem könnte man noch eine Funktion schreiben, die ermittelt, wie „gut“ das Resultat ist, die also bewertet, dass „Leseziechen“ weniger gut ist als „Lzecheseein“. Bei Bedarf könnte so der Algorithmus solange durchgeführt werden, bis ein zufriedenstellendes Ergebnis erreicht wird. (Wobei dort sichergestellt sein muss, dass ein „zufriedenstellendes“ Ergebnis existiert. Sonst gibt es eine Endlosschleife.)

Ein weiterer Faktor, der berücksichtigt werden könnte: Eine Anordnung „Leeeeizshcn“ oder „Lzshceeeein“, bei der die Vokale und Konsonanten schlecht verteilt sind, ist möglicherweise auch nicht erstrebenswert.
 
Zuletzt bearbeitet:
Das siehst du falsch. Wenn der an str_split übergebene String leer ist (oder allgemein: kürzer als der zweite optionale Parameter split_length, sofern dieser >0 ist), wird ein Array zurückgegeben, das als einziges Element den gesamten String enthält.

Jep hast Recht. Hatte mich gestern in der Doku verlesen gehabt. Sollte mir unbedingt abgewöhnen zu später Stunde noch was zu schreiben.

Überleg dir lieber noch mal in Ruhe, was mein Code genau tut (der Aufruf von shuffle zum Beispiel).

Mit shuffle würfelst du das Array durcheinander. Es ginge auch mit str_shuffle().
 
Werbung:
Okay, stimmt. Glaube aber, wenn du UTF-8 willst (was wir hoffentlich alle tun), ist es so oder so die Lösung mit preg.

Na ja, wie gesagt, wäre eine ganz witzige Aufgabe für Main - phpGolf, auch wenn vom „Algorithmus“ wohl etwas zu simpel.
 
PHP:
function switch( $string, $counter=0 ){

  $count = $counter>0?$counter:sizeof( $string )+5;

  foreach ( $x = 0; $x < $count; $x++ ){
     $random = rand( 1, sizeof( $string )-1 );

     while( $random2 == $random ){
        $random2 = rand( 1, sizeof( $string )-1 );    
     }
   
     $temp = $string[ $random1 ];
     $string[ $random1 ] = $string[ $random2 ];
     $string[ $random2 ] = $temp;
  }
  return $string;
}

$test = 'Willkommen';
echo switch( $test );

Mich würde es tierisch Interessieren, ob das hier klappt.. ist mir ganz Spontan eingefallen^^ Ich glaub sowas haben wir vor paar Jahren in der Schule mit C++ gemacht :p

$string : Das Wort
$counter : Häufigkeit des vertauschens, falls 0 angegeben wird, wird die Länge des Wortes + 5 mal genommen.

Es werden zwei unterschiedliche zufällig Zahlen generiert welche für die Buchstaben stehen, die zwischen 1 und der Länge des Wortes Minus eins liegen. ( Willkommen = illkomme )

Der erste Buchstabe wird in einer Temporären Variable gespeichert, der zweite kommt in den ersten und der zweite bekommt die Temporäre.. den Vorgang mehrmals wiederholt und alles sollte vertauscht sein.
 
Erstmal vielen Dank für die Antworten! Ich habe nun die Lösung von Threadi benutzt - vielen Dank für den Link und auch die anderen Vorschläge werde ich mir noch anschauen und versuchen daraus zu lernen :)

zorndyuke: Nein dein Code funktioniert nicht, mehrere Syntaxfehler ;)
 
Werbung:
Zurück
Oben