我在某个地方遇到了这个问题,我想知道如何使用PHP解决这个问题。鉴于此文:
$str = '
PHP is a
widely-used
general-purpose
server side
scripting
language
';
如何垂直回显文本,如下所示:
g
e
n
e
w r s
i a e
d l r s
P e - v c l
H l p e r a
P y u r i n
- r p g
i u p s t u
s s o i i a
e s d n g
a d e e g e
我会选择更简单,更优雅的代码作为答案。
答案 0 :(得分:9)
正如其他人已经证明的那样,array_map
能够进行翻转,这基本上是您需要解决的主要问题。剩下的就是你如何安排代码。我认为你的版本非常好,因为它很容易理解。
如果你正在寻找更多其他极端,请小心处理:
$str = 'PHP is a
widely-used
general-purpose
server side
scripting
language';
$eol = "\n";
$turned = function($str) use ($eol) {
$length = max(array_map('strlen', $lines = explode($eol, trim($str))));
$each = function($a, $s) use ($length) {$a[] = str_split(sprintf("%' {$length}s", $s)); return $a;};
return implode($eol, array_map(function($v) {return implode(' ', $v);}, call_user_func_array('array_map',
array_reduce($lines, $each, array(NULL)))));
};
echo $turned($str), $eol;
给你:
g
e
n
e
w r s
i a e
d l r s
P e - v c l
H l p e r a
P y u r i n
- r p g
i u p s t u
s s o i i a
e s d n g
a d e e g e
这会修复另一个答案的输出,这是不正确的(现在已修复)。
答案 1 :(得分:6)
以下代码将垂直打印$str
。
$lines = preg_split("/\r\n/", trim($str));
$nl = count($lines);
$len = max(array_map('strlen', $lines));
foreach ($lines as $k => $line) {
$lines[$k] = str_pad($line, $len, ' ', STR_PAD_LEFT);
}
for ($i = 0; $i < $len; $i++) {
for ($j = 0; $j < $nl; $j++) {
echo $lines[$j][$i].($j == $nl-1 ? "\n" : " ");
}
}
答案 2 :(得分:3)
我从@bsdnoobz获取了一些代码并对其进行了简化。我正在使用\ n作为换行符,因为我在Mac上工作并且\ r \ n doean在这里工作。
$lines = preg_split("/\n/", trim($str));
$len = max(array_map('strlen', $lines));
$rows = array_fill(0,$len,'');
foreach ($lines as $k => $line) {
foreach (str_split(str_pad($line, $len, ' ', STR_PAD_LEFT)) as $row => $char){
$rows[$row] .= $char;
}
}
echo implode("\n",$rows)."\n";
答案 3 :(得分:3)
$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”或“&lt; br /&gt;”在适当情况下。第一行之后的整个代码很容易成为一个大表达式,只有它的可读性会受到一点影响; - )
$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函数中的循环更昂贵,尽管在这种情况下优势可能会丢失)。这里的重要技巧是矩阵换位,我从this answer by Codler
取得无论如何,整个算法的复杂性是O(width × height)
,就像本页大多数算法之一一样,除了重复连接字符串以获得行的那些,其复杂度为{{1} }
答案 4 :(得分:1)
我会试一试:
$arrlines = explode(PHP_EOL, trim($str));
$max = max(array_map('strlen', $arrlines));
foreach($arrlines as $val)
$arrlines = str_pad($val,$max," ",STR_PAD_LEFT);
for($x=0;$x<$max;$x++){
for($y=0;$y<count($arrlines);$y++)
$string .= strlen(trim($arrlines[$y][$x])) > 0 ? $arrlines[$y][$x]." ":" ";
$string .= "\n";
}
echo '<pre>'.$string.'</pre>';
行号:
对于第5-9行,嵌套循环将$ arrline [$ y] [$ x]保存到$ string,第10行输出结果。
可以找到结果here。
答案 5 :(得分:0)
这是我的镜头。没有嵌套循环,无法弄清楚如何做到这一点。
$lines = array_map('strrev', explode("\r\n", trim($str)));
$new = array();
foreach(range(0, max(array_map('strlen', $lines))) as $i){
foreach($lines as $line){
$new[$i] .= (!empty($line[$i]) ? $line[$i] . ' ' : ' ');
}
}
echo implode("\r\n", (array_slice(array_reverse($new), 1)));
答案 6 :(得分:0)
我无需任何循环即可旋转文本的功能:
/**
* Rotates text
*
* @param string $str String to rotate
*
* @return string Rotated string
*/
function rotateText($str)
{
$lines = explode(PHP_EOL, $str);
$lengths = array_map('strlen', $lines);
$maxLength = max($lengths);
$lines = array_map(function ($line) use ($maxLength) {
return str_pad($line, $maxLength, ' ', STR_PAD_LEFT);
}, $lines);
$chars = array_map('str_split', $lines);
array_unshift($chars, null);
$rotatedLines = call_user_func_array('array_map', $chars);
$rotatedText = join(PHP_EOL, array_map('join', $rotatedLines));
return $rotatedText;
}
echo "<pre>", rotateText($str), "</pre>";
答案 7 :(得分:0)
请注意,每个变量的PHP缓存字符串的长度和数组中的元素数。重复调用strlen或count只会导致空函数调用的性能损失(在后续调用中,PHP内部不会测量长度或计数两次)。
适用于Mac(\ r),Linux(\ n)或Windows(\ r \ n)输入字符串,和/或空输入字符串,和/或一行输入字符串,以及输出使用首选行分隔符(默认为PHP_EOL):
function matrix_vertical_align_bottom($str, $strEOL=PHP_EOL)
{
$arrLines=explode("\n", $str);
$nMaxLength=max(array_map("strlen", $arrLines));
$nRotatedWidth=count($arrLines)+strlen($strEOL);
//allocate once
$strRotated=str_pad(
"",
$nRotatedWidth*$nMaxLength-strlen($strEOL),
str_repeat(" ", count($arrLines)).$strEOL
);
foreach($arrLines as $nRotatedColumnIndex=>$strLine)
{
$nRotatedVerticalPadding=$nMaxLength-strlen($strLine);
for($nColumnIndex=strlen($strLine)-1; $nColumnIndex>=0; $nColumnIndex--)
$strRotated[$nRotatedWidth*($nColumnIndex+$nRotatedVerticalPadding)+$nRotatedColumnIndex]=$strLine[$nColumnIndex];
}
return $strRotated;
}
echo matrix_vertical_align_bottom(preg_replace("/(\r\n|\r|\n)/", "\n", trim($str)));
性能非常好,上面的算法只是在将字符串旋转90度时平移坐标。没有内存重新分配,因为填充单个行引起的字符串扩展(对于具有大量行的输入字符串,这将是性能损失)。
不假设HTML输出,nl2br(htmlspecialchars())输出时应该执行技巧+单声道间隔字体。
答案 8 :(得分:0)
以下是任何人都可以理解此代码的简单代码
$str = '
PHP is a
widely-used
general-purpose
server side
scripting
language
';
$lines = array();
$sentences = explode("\n\n",$str);
foreach($sentences as $sentence){
if($sentence != ""){
$each_lines = explode("\n",$sentence);
foreach($each_lines as $each_line){
if($each_line != ""){
$lines[] = $each_line;
}
}
$lines[] = "\t";
}
}
$before_sort = $lines;
usort($lines, "cmp_len");
$big_length = strlen($lines[0]);
foreach($before_sort as $key=>$arr){
$this_length = strlen($arr);
if($this_length < $big_length){
$no_of_letters = $big_length - $this_length;
$text = "";
for($i=0;$i<$no_of_letters;$i++){
$text .= " ";
}
$text .= $before_sort[$key];
$before_sort[$key] = $text;
}
}
$temp = array();
echo "<table>";
for($i=0;$i<$big_length;$i++){
echo "<tr>";
foreach($before_sort as $arr){
echo "<td>";
echo str_replace("\t"," ",$arr[$i]);
echo "</td>";
}
echo "</tr>";
}
echo "</table>";
function cmp_len($a, $b){
return (strlen($a) < strlen($b));
}
答案 9 :(得分:0)
检查这个答案:
<?php
$str = 'PHP is a
widely-used
general-purpose
server side
scripting
language';
function getVerticalString($str){
$str = preg_split('/\r|\n/',$str);
$maxlength = 0;
$totalstr = count($str);
for($i=0;$i<$totalstr;$i++){
if($maxlength<strlen($str[$i])){
$maxlength = strlen($str[$i]);
}
}
$strings = array();
for($i=0;$i<$maxlength;$i++){
$strings[$i] = "";
for($j=0;$j<$totalstr;$j++){
$temp = strlen($str[$j])-($maxlength-$i);
if($temp>=0){
$strings[$i] .= substr($str[$j],$temp,1);
}
else{
$strings[$i] .= " ";
}
}
}
return implode("\r",$strings);
}
echo "<pre>".getVerticalString($str)."</pre>";
此输出:
g
e
n
e
w rs
i ae
d lr s
Pe -v cl
Hl pe ra
Py ur in
- r pg
iu ps tu
ss oi ia
e sd ng
ad ee ge
根据您的要求。 :)
答案 10 :(得分:0)
我不会把它称为更短,但行数更少; - )
$nr_lines = count($lines = preg_split('/\r?\n/', trim($str)));
$maxlen = max($lengths = array_map('strlen', $lines)); // get line lengthts and maximum
$line_ptrs = array_fill(0, $nr_lines, 0); // last character position per line
for ($j = 0; $j != $maxlen; ++$j) {
for ($i = 0; $i != $nr_lines; ++$i) {
// $maxlen - $lengths[$i] indicates where printing start for this line
echo $j >= $maxlen - $lengths[$i] ? $lines[$i][$line_ptrs[$i]++] : ' ';
}
echo "\n";
}
它在同一内循环中进行填充和打印,在$line_ptrs
和$lengths
数组的帮助下跟踪下一个要打印的字符。
<强>基准强>
基于10,000次迭代,此代码比第一个答案好19%。
答案 11 :(得分:0)
试试这个,
$str = 'PHP is a
widely-used
general-purpose
server side
scripting
language';
$strArr = explode("\r\n", $str);
$max =max(array_map('strlen', $strArr));
for($i=0; $i< $max;$i++)
{
for($x=0;$x < count($strArr); $x++)
{
$strVal = $strArr[$x];
$y = $i -($max - strlen($strVal));
$vertical .= strlen(trim($strVal[$y]))<> 0 ? $strVal[$y]." " : " ";
}
$vertical .="\n";
}
echo "<pre>".$vertical;
答案 12 :(得分:0)
最好最简单的方法:)
<style type="text/css">
#heading{
/* vertical text css */
width:1em;
text-transform:uppercase;
}
</style>
<h1 align="center" id="heading">h e l l o</h1>
答案 13 :(得分:0)
>>> data = {("16741b673a418af3812f6d43ea3f7daf", 1132): ["data-01", "data-02", "data-03"],
... ("cbef6de99cc2b9739c824db6d0246093", 55296): ["data-04", "data-05", "data-06", "data-07"],
... ("a1e0f7ccdd8d38cb5ae00cdac71b6724", 20125): ["data-08", "data-09", "data-10"]}
>>>
>>> {k: v for k, v in sorted(data.items(), key=lambda x: x[0][1])}