$a = explode(PHP_EOL, trim($str));
$h = max(array_map('strlen', $a));
$w = count($a);
$m = array_map('str_split', array_map('sprintf', array_fill(0, $w, "%{$h}s"), $a));
$t = call_user_func_array('array_map', array_merge(array(null), $m));
echo implode(PHP_EOL, array_map('implode', array_fill(0, $h, ' '), $t)), PHP_EOL;
PHP_EOLは、必要に応じて「\ n」、「\ r \ n」、または「<br/>」に置き換える必要があります。最初の行の後のコード全体が簡単に1つの大きな式になる可能性があり、その可読性だけが少し損なわれます;-)
$a
は行の配列、$h
は最終的な高さ、$w
は最終的な幅、$m
は文字の行列(文字列をパディングした後)、$t
は転置された行列です。
列間のarray_fill(0, $h, ' '),
スペースが必要ない場合は、最後の行のを単純に省略できます。一方、末尾のスペース文字を印刷しないことは、次のように実現できます。
echo implode(PHP_EOL, array_map('rtrim', array_map('implode', array_fill(0, $h, ' '), $t))), PHP_EOL;
私はこの質問を、明示的なループ(この場合は利点が失われる可能性がありますが、通常はPHP関数内のループよりも高価です)を回避するための演習として取り上げました。ここで重要なトリックは、Codlerによるこの回答から取ったマトリックス転置です。
とにかく、アルゴリズム全体の複雑さは、O(width × height)
このページのほとんどのアルゴリズムの1つと同じですが、行を取得するために文字列を繰り返し連結するアルゴリズムを除きます。O(width² × height)