打印围城

题目

写一个脚本,这个脚本可以输入多个参数,参数不可少于两个,执行完成后输出回形矩阵,具体查看下面两个例子的结果。

示例

示例1:

执行脚本命令,传入三个参数: php test.php a b c

脚本执行输出结果:

a a a a a
a b b b a
a b c b a
a b b b a
a a a a a

示例2:

执行脚本命令,传入两个参数: php test.php a b

脚本执行输出结果:

a a a
a b a
a a a

提示

执行结果其实是一个 2n-1 * 2n-1 的数组,而且是一个轴对称的数组。

解析思路

利用其轴对称的特性,拼凑出上面的一部分,并复制反转,将两个数组合并成一个新的数组,最终输出结果。

假设:

有三个参数,这三个参数分别是: abc

脚本执行结果如下:

a a a a a
a b b b a
a b c b a
a b b b a
a a a a a

观察执行结果:

  • 每行都有第一个参数 a
  • 整个数组相对于第 n 行轴对称,相对于第 n 列轴对称
  • 第一行之后第一个参数,第二行有第一和第二个参数,以此类推到 n
  • 结果总共有 2n-1 行,2n-1

具体解题思路:

第一步:生成 n 行值为第一个参数 a 的数组。

$line = array_fill(0, $len * 2 - 1, 'a');
$rows = array_fill(0, $len, $line);

第二步:逐步替换每行的内容,并逐步替换每行的内容,这里以第三行举例

// 原始
// ['a', 'a', 'a', 'a', 'a']

// 第一次替换
// ['a', 'b', 'b', 'b', 'a']

// 第二次替换
// ['a', 'b', 'c', 'b', 'a']

$argv = ['a', 'b', 'c'];
$len = count($argv);
$maxLen = $len * 2 - 1;
foreach ($rows as $key => &$row) {
    for ($i = 1; $i <= $key; $i++) {
        $line = array_fill($i, $maxLen - $i * 2, $argv[$i]);
        $row = array_replace($row, $line);
    }
}

// ['a', 'a', 'a', 'a', 'a']
// ['a', 'b', 'b', 'b', 'a']
// ['a', 'b', 'c', 'b', 'a']

第三步:复制已经获得的结果,然后反转

$rest = array_reverse($rows);

// ['a', 'b', 'c', 'b', 'a']
// ['a', 'b', 'b', 'b', 'a']
// ['a', 'a', 'a', 'a', 'a']

第四步:去除反转数组的第一行

array_shift($rest);

// ['a', 'b', 'b', 'b', 'a']
// ['a', 'a', 'a', 'a', 'a']

第五步:拼接反转前和反转处理后的数组

array_merge($rows, $rest);

// ['a', 'a', 'a', 'a', 'a']
// ['a', 'b', 'b', 'b', 'a']
// ['a', 'b', 'c', 'b', 'a']
// ['a', 'b', 'b', 'b', 'a']
// ['a', 'a', 'a', 'a', 'a']

大功告成。

完整代码

这里提供了多个版本的解题方法
后续可能会增加其它语言的解题方法

PHP版本

$argv = ['👦', '❤️', '🐘'];
$len = count($argv);
$maxLen = 2*$len-1;
$line = array_fill(0, $maxLen, reset($argv));
$rows = array_fill(0, $len, $line);
foreach ($rows as $key => &$row) {
    for ($i = 1; $i <= $key; $i++) {
        $line = array_fill($i, $maxLen - $i * 2, $argv[$i]);
        $row = array_replace($row, $line);
    }
}
unset($row);
$rest = array_reverse($rows);
array_shift($rest);
$result = array_merge($rows, $rest);

// 👦 👦 👦 👦 👦
// 👦 ❤️ ❤️ ❤️ 👦
// 👦 ❤️ 🐘 ❤️ 👦
// 👦 ❤️ ❤️ ❤️ 👦
// 👦 👦 👦 👦 👦

JS版本

这里需要注意的是,JS 的数组是用引用的方式传递的,如果想要复制,必须深复制,不然会发生改变复制数组,造成原数组同时改变的结果。

var argv = ['a', 'b', 'c']
var len = argv.length, maxLen = 2 * len - 1
var rows = Array(len).fill(0)
var result = []
for (var i in rows) {
    i = parseInt(i)
    rows[i] = Array(maxLen).fill(argv[0])
    for (var j = 1; j <= i; j++) {
        rows[i].fill(argv[j], j, maxLen - j)
    }
}
var rest = [].concat(rows)
rest.pop()
rest.reduceRight(function (previous, current) {
    previous.push(current)
    return previous
}, rows)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 12,448评论 6 13
  • 2018web前端最新面试题总结 一、Html/Css基础模块 基础部分 什么是HTML?答:​ HTML并不是...
    duans_阅读 4,717评论 3 27
  • 昨天,孩子让我坐在她的身旁陪着她写作业,我一猜应该是有算术题,果然没错。听老师说,在学校老师一讲完,让她们上去...
    那一丝风阅读 153评论 0 1
  • 水彩泡泡,跟今天的天气一样灿烂,嘻嘻 第7天打卡
    望氨阅读 225评论 0 0
  • 如何让夫妻间的关系越来越好? 目前我们夫妻之间的关系和谐,但不完善,家里的经济一向以我先生主导,先生买了两套房子,...
    颜燕静阅读 222评论 0 0

友情链接更多精彩内容