php风车,PHP 面试 风车算法

这篇博客分享了一道面试题的解决方案,涉及编写一个PHP函数`foo`,该函数能够根据参数实现矩阵的顺时针或逆时针旋转。通过坐标化处理和迭代填充,函数能生成指定尺寸和旋转方向的旋转矩阵,并最终将其按行分组。博客详细解释了代码逻辑和关键函数`create_struct`、`change_key`的实现过程。
摘要由CSDN通过智能技术生成

最近在面试的过程中遇到了一个挺有意思的 面试题, 让写一个 函数 效果如下:

foo(4); // 调用函数foo 传参数 效果如下:

/**

7, 8, 9, 10

6, 1, 2, 11

5, 4, 3, 12

16,15,14,13

*/

foo(5); //调用函数foo 传参数 效果如下:

/**

13,14,15,16, 17

12, 3, 4, 5, 18

11, 2, 1, 6, 19

10, 9, 8, 7, 20

25, 24,23,22,21

*/

foo($n)

按照上面的结果,分析了下整了如下函数:

/**

* @param $num

* @param int $direction 方向 1 为 顺时针旋转 2 为逆时针旋转

* @return mixed

*/

function foo($num, $direction = 1)

{

//填充map

$data = new stdClass();

$data->x = 1;

if ($direction == 1) {

$data->y = $num;

} elseif ($direction == 2) {

$data->y = 1;

}

$data->num = $num;

$data->len = $num * $num;

$data->tmp_data = [];

$data->rate = 1;//方向

$data->struct = create_struct($num);

for ($i = $data->len; $i >= 1; $i--) {

$data->i = $i;

$key = change_key($data, $direction);

$data->tmp_data[$key] = $i;

unset($data->struct[$key]);

}

//根据y坐标分组

$data->struct = create_struct($num);

foreach ($data->tmp_data as $key => $value) {

$data->struct[$key] = $value;

}

for ($i = 1; $i <= $data->num; $i++) {

$start = ($i - 1) * $data->num;

$end = $data->num;

$slice = array_slice($data->struct, $start, $end);

$data->slice[] = $slice;

}

return $data->slice;

}

function create_struct($num)

{

$struct = [];

for ($i = 1; $i <= $num; $i++) {

//嵌套

for ($m = 1; $m <= $num; $m++) {

$key = $m.','.$i;

$struct[$key] = '';

}

}

return $struct;

}

function change_key($data, $direction)

{

$key = $data->x.','.$data->y;

if (isset($data->struct[$key])) {

return $key;

}

switch ($data->rate) {

// LEFT 方向

case 1:

$data->tmp_x = $data->x + 1;

$key = $data->tmp_x.','.$data->y;

if (isset($data->struct[$key])) {

$data->x = $data->tmp_x;

return $key;

} else {

if ($direction = 1) {

$data->rate = 4;

} elseif ($direction = 2) {

$data->rate = 2;

}

}

break;

// DOWN 方向

case 2:

$data->tmp_y = $data->y + 1;

$key = $data->x.','.$data->tmp_y;

if (isset($data->struct[$key])) {

$data->y = $data->tmp_y;

return $key;

} else {

if ($direction = 1) {

$data->rate = 1;

} elseif ($direction = 2) {

$data->rate = 3;

}

}

break;

// RIGHT 方向

case 3:

$data->tmp_x = $data->x - 1;

$key = $data->tmp_x.','.$data->y;

if (isset($data->struct[$key])) {

$data->x = $data->tmp_x;

return $key;

} else {

if ($direction = 1) {

$data->rate = 2;

} elseif ($direction = 2) {

$data->rate = 4;

}

}

break;

// UP 方向

case 4:

$data->tmp_y = $data->y - 1;

$key = $data->x.','.$data->tmp_y;

if (isset($data->struct[$key])) {

$data->y = $data->tmp_y;

return $key;

} else {

if ($direction = 1) {

$data->rate = 3;

} elseif ($direction = 2) {

$data->rate = 1;

}

}

break;

}

return change_key($data, $direction);

}

其中原理是把效果按照 坐标的形式去处理,比如:

foo(4) 按照坐标化处理就是:

7, 8, 9, 10 1,1 2,1 3,1 4,1

6, 1, 2, 11 1,2 2,2 3,2 4,2

5, 4, 3, 12 1,3 2,3 3,3 4,3

16,15,14,13 1,4 2,4 3,4 4,4

然后我们通过 create_struct() 函数去组合一下 坐标:

array (size=16)

'1,1' => string '' (length=0)

'2,1' => string '' (length=0)

'3,1' => string '' (length=0)

'4,1' => string '' (length=0)

'1,2' => string '' (length=0)

'2,2' => string '' (length=0)

'3,2' => string '' (length=0)

'4,2' => string '' (length=0)

'1,3' => string '' (length=0)

'2,3' => string '' (length=0)

'3,3' => string '' (length=0)

'4,3' => string '' (length=0)

'1,4' => string '' (length=0)

'2,4' => string '' (length=0)

'3,4' => string '' (length=0)

'4,4' => string '' (length=0)

从算法结果要求对比我们会发现旋转的最后一个值我们是知道的:

/**

7, 8, 9, 10

6, 1, 2, 11

5, 4, 3, 12

16,15,14,13

*/

// 最后一个值是 16 foo(4)

/**

13,14,15,16, 17

12, 3, 4, 5, 18

11, 2, 1, 6, 19

10, 9, 8, 7, 20

25, 24,23,22,21

*/

// 最后一个值是 25 foo(5)

也就是最后一个值 是 $num*$num 最后一个值的坐标是 (1,$num)

接下来我们遍历坐标倒着把外圈的先整出来,代码如下:

$data = new stdClass(); //PHP内置类 用来返回特定的数据结构

$data->x = 1;

if ($direction == 1) {

$data->y = $num;

} elseif ($direction == 2) {

$data->y = 1;

}

$data->num = $num;

$data->len = $num * $num;

$data->tmp_data = [];

$data->rate = 1;//方向

$data->struct = create_struct($num);

for ($i = $data->len; $i >= 1; $i--) {

$data->i = $i;

}

var_dump($data);

运行这段代码如下:

object(stdClass)[1]

public 'x' => int 1

public 'y' => int 4

public 'num' => int 4

public 'len' => int 16

public 'tmp_data' =>

array (size=0)

empty

public 'rate' => int 1

public 'struct' =>

array (size=16)

'1,1' => string '' (length=0)

'2,1' => string '' (length=0)

'3,1' => string '' (length=0)

'4,1' => string '' (length=0)

'1,2' => string '' (length=0)

'2,2' => string '' (length=0)

'3,2' => string '' (length=0)

'4,2' => string '' (length=0)

'1,3' => string '' (length=0)

'2,3' => string '' (length=0)

'3,3' => string '' (length=0)

'4,3' => string '' (length=0)

'1,4' => string '' (length=0)

'2,4' => string '' (length=0)

'3,4' => string '' (length=0)

'4,4' => string '' (length=0)

public 'i' => int 1

得到一个对象有开始 坐标 有 最后一个 点的值 然后我们开始用 change_key() 函数迭代,先给 1,4 坐标分配一个 16 代码如下:

$key = change_key($data, $direction);

$data->tmp_data[$key] = $i;

unset($data->struct[$key]);

然后在 change_key() 递归调用 填充 , 依次 向右走->向上->向左-> 向下 这样 得到数据如下:

object(stdClass)[1]

public 'x' => int 2

public 'y' => int 2

public 'num' => int 4

public 'len' => int 16

public 'tmp_data' =>

array (size=16)

'1,4' => int 16

'2,4' => int 15

'3,4' => int 14

'4,4' => int 13

'4,3' => int 12

'4,2' => int 11

'4,1' => int 10

'3,1' => int 9

'2,1' => int 8

'1,1' => int 7

'1,2' => int 6

'1,3' => int 5

'2,3' => int 4

'3,3' => int 3

'3,2' => int 2

'2,2' => int 1

public 'rate' => int 3

public 'struct' =>

array (size=0)

empty

public 'i' => int 1

public 'tmp_x' => int 2

public 'tmp_y' => int 1

接下来一行一行的排列了代码如下:

$data->struct = create_struct($num);

foreach ($data->tmp_data as $key => $value) {

$data->struct[$key] = $value;

}

结果如下:

object(stdClass)[1]

public 'x' => int 2

public 'y' => int 2

public 'num' => int 4

public 'len' => int 16

public 'tmp_data' =>

array (size=16)

'1,4' => int 16

'2,4' => int 15

'3,4' => int 14

'4,4' => int 13

'4,3' => int 12

'4,2' => int 11

'4,1' => int 10

'3,1' => int 9

'2,1' => int 8

'1,1' => int 7

'1,2' => int 6

'1,3' => int 5

'2,3' => int 4

'3,3' => int 3

'3,2' => int 2

'2,2' => int 1

public 'rate' => int 3

public 'struct' =>

array (size=16)

'1,1' => int 7

'2,1' => int 8

'3,1' => int 9

'4,1' => int 10

'1,2' => int 6

'2,2' => int 1

'3,2' => int 2

'4,2' => int 11

'1,3' => int 5

'2,3' => int 4

'3,3' => int 3

'4,3' => int 12

'1,4' => int 16

'2,4' => int 15

'3,4' => int 14

'4,4' => int 13

public 'i' => int 1

public 'tmp_x' => int 2

public 'tmp_y' => int 1

最后 把 $data->struct属性 按照 $num 进行分组就 ok了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值