题目
写一个脚本,这个脚本可以输入多个参数,参数不可少于两个,执行完成后输出回形矩阵,具体查看下面两个例子的结果。
示例
示例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
的数组,而且是一个轴对称的数组。
解析思路
利用其轴对称的特性,拼凑出上面的一部分,并复制反转,将两个数组合并成一个新的数组,最终输出结果。
假设:
有三个参数,这三个参数分别是: 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
观察执行结果:
- 每行都有第一个参数
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)
网友评论