PHP 问题:PHP 脚本形状
问题
编写一个PHP脚本,以正确的菱形打印出以下文本。
* *** ***** ******* ********* ********* ******* ***** *** *
回答
钻石形状由10个“级别”的星星组成。每个级别由一颗或多颗星星和一些将中间的星星推入线中间的空白组成。每条线还必须由奇数个星星组成,因为偶数个开头不能有中间星星。
我们绘制形状需要做的是从1开始循环,直到我们到达星星的中间,然后再往下走,直到再次到达1。因为我们只使用奇数,所以我们可以简单地使用10作为级别数的计数,然后增加2直到我们达到该值,然后再次减少数字。在降低级别时,我们唯一需要更改的是检查奇数或偶数级别。如果数字是偶数,那么我们需要去掉1,这样我们仍然在计算奇数。空格可以通过用级别数减去增量值来计算。
我们可以使用PHPstr_pad()函数,而不是对空格和星号进行单独循环。第二个参数是字符串必须是的长度,第三个参数是自定义填充值,我们可以放一个空格或一个星号。第一个参数是我们需要填充的字符串,但由于这里不会使用它,我们可以只输入一个空白字符串。
因此,我们最终得到了这段代码。
//明星之巅 for ($i = 1; $i <= $levels; $i = $i + 2) { $whitespace = ($levels - $i / 2); echo str_pad('', $whitespace, ' ') . str_pad('', $i, '*') . "\n"; } //奇数或偶数级别? if ($levels % 2 == 0) { $downlevels = $levels - 1; } else { $downlevels = $levels; } //星底 for ($i = $downlevels; $i >= 0; $i = $i - 2) { $whitespace = ($levels - $i / 2); echo str_pad('', $whitespace, ' ') . str_pad('', $i, '*') . "\n"; }
你们中的一些人可能已经注意到我们在这里做了两次同样的事情。本质上,第二个循环是重复第一个循环所做的工作,只是方向相反。为了提高此代码的效率,我们可以做的是删除第二个循环并使第一个循环创建一系列数组元素。然后,我们可以使用PHPimplode()和array_reverse()函数的组合来打印单次循环运行的输出。更改上面的代码以合并这些功能,我们得到以下代码。
$levels = 10; $output = array(); for ($i = 1; $i <= $levels; $i = $i + 2) { $whitespace = ($levels - $i / 2); $output[] = str_pad('', $whitespace, ' ') . str_pad('', $i, '*'); } echo implode("\n", $output); echo "\n"; echo implode("\n", array_reverse($output)); echo "\n";
这将打印出以下内容。
* *** ***** ******* ********* ********* ******* ***** *** *
我们可以通过删除形状左侧的大量空白对生成的输出进行一些最终整理。为此,我们创建一个空白因子变量,它是级别数的一半,然后从生成的空白量中减去它。我们还可以将代码包装在函数调用中,以便在运行时更方便。
function draw_diamond($levels) { $whitespaceFactor = $levels/2; $output = array(); for ($i = 1; $i <= $levels; $i = $i + 2) { $whitespace = ($levels - $i / 2) - $whitespaceFactor; $output[] = str_pad('', $whitespace, '-') . str_pad('', $i, '*'); } echo implode("\n", $output); echo "\n"; echo implode("\n", array_reverse($output)); echo "\n"; } draw_diamond(10);
运行上面的代码会给我们以下输出,这正是我们正在寻找的形状。
* *** ***** ******* ********* ********* ******* ***** *** *