PHP:确定2个网格之间的网格数 [英] PHP: Determining Grid Count Between 2 Grids

查看:72
本文介绍了PHP:确定2个网格之间的网格数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

允许对角移动

我有一个5x5的网格(虽然会逐渐增加到30x30或更大,只是为了使自己更容易一些而已,但我正在尝试确定2个网格之间的网格数,但是,这是我的努力,希望有人可以指出我正确的方向.我想要实现的基本上是用户选择2个网格,即30043017,然后应该找到最短的路线并计算网格.例如,30043017之间的网格数应为430013005之间的网格数应为530013017之间的网格数应为430013002之间的网格数应为2,等等.

网格:

------------------------------------
| 3001 | 3002 | 3003 | 3004 | 3005 |
------------------------------------
| 3006 | 3007 | 3008 | 3009 | 3010 |
------------------------------------
| 3011 | 3012 | 3013 | 3014 | 3015 |
------------------------------------
| 3016 | 3017 | 3018 | 3019 | 3020 |
------------------------------------
| 3021 | 3022 | 3023 | 3024 | 3025 |
------------------------------------

我的数组的结构如下:

$grids = array(
    1 => array(
        1 => 3001,
        2 => 3002,
        3 => 3003,
        4 => 3004,
        5 => 3005
    ),
    2 => array(
        1 => 3006,
        2 => 3007,
        3 => 3008,
        4 => 3009,
        5 => 3010
    ),
    3 => array(
        1 => 3011,
        2 => 3012,
        3 => 3013,
        4 => 3014,
        5 => 3015
    ),
    4 => array(
        1 => 3016,
        2 => 3017,
        3 => 3018,
        4 => 3019,
        5 => 3020
    ),
    5 => array(
        1 => 3021,
        2 => 3022,
        3 => 3023,
        4 => 3024,
        5 => 3025
    ),
);

我尝试过的事情:

我意识到我可以使用旧的斜边 a 2 + b 2 = c 2

在几个示例中,效果很好,但并非每次都如此.例如,如果我插入30043017,则网格数应为4,但是,它会吐出5,或者如果我插入30013025,则网格数应为,它在网格本身之外.我确实知道为什么会出现这些结果,所以我想检查是否有一种方法可以改进公式以使其以某种方式起作用?

这个问题正在使我丧命,因为我已经接近可以品尝到的解决方案了.

非常感谢您预先提供的所有帮助!

我当前的代码:(请谅解)

<style>
.grid {
    display: inline-block;
    line-height: 50px; padding-left: 10px; padding-right: 10px;
    border:1px solid black;
}
.grid.active {
    background: red;
}
</style>
<?php

/*
3001  3002  3003  3004  3005
3006  3007  3008  3009  3010
3011  3012  3013  3014  3015
3016  3017  3018  3019  3020
3021  3022  3023  3024  3025
*/

$from = 3001;
$to   = 3025;

$grids = array(
    1 => array(
        1 => 3001,
        2 => 3002,
        3 => 3003,
        4 => 3004,
        5 => 3005
    ),
    2 => array(
        1 => 3006,
        2 => 3007,
        3 => 3008,
        4 => 3009,
        5 => 3010
    ),
    3 => array(
        1 => 3011,
        2 => 3012,
        3 => 3013,
        4 => 3014,
        5 => 3015
    ),
    4 => array(
        1 => 3016,
        2 => 3017,
        3 => 3018,
        4 => 3019,
        5 => 3020
    ),
    5 => array(
        1 => 3021,
        2 => 3022,
        3 => 3023,
        4 => 3024,
        5 => 3025
    ),
);

$from_cells = 1;
$from_rows  = 1;

foreach ( $grids as $y => $xs )
{
    $from_cells = 1;

    foreach ( $xs as $x => $postcode )
    {
        if ( $postcode == $from )
        {
            break 2;
        }
        else
        {
            $from_cells++;
        }
    }

    $from_rows++;
}

$to_cells = 1;
$to_rows  = 1;

foreach ( $grids as $y => $xs )
{
    $to_cells = 1;

    foreach ( $xs as $x => $postcode )
    {
        if ( $postcode == $to )
        {
            break 2;
        }
        else
        {
            $to_cells++;
        }
    }

    $to_rows++;
}

echo "From<hr/>X: $from_cells | Y: $from_rows<br/><hr/>To<hr/>X: $to_cells | Y: $to_rows";

$leg1 = 0;
$leg2 = 0;

$cell_short = ($from_cells < $to_cells) ? $from_cells : $to_cells;
$cell_long  = ($from_cells > $to_cells) ? $from_cells : $to_cells;

for ( $i=$cell_short; $i <= $cell_long; $i++ )
{
    $leg1 = $i;
}

$row_short = ($from_rows < $to_rows) ? $from_rows : $to_rows;
$row_long  = ($from_rows > $to_rows) ? $from_rows : $to_rows;

for ( $i=$row_short; $i <= $row_long; $i++ )
{
    $leg2 = $i;
}

echo "<hr/>Length: $leg1<br/>Height: $leg2";

$grid_count = pow($leg1,2) + pow($leg2,2);
$grid_count = floor(sqrt($grid_count));

echo "<hr/>Grids: $grid_count<hr/>";

foreach ( $grids as $y => $xs )
{
    foreach ( $xs as $x => $postcode )
    {
        if ( $postcode == $from or $postcode == $to )
        {
            echo '<div class="grid active">'.$postcode.'</div>';
        }
        else
        {
            echo '<div class="grid">'.$postcode.'</div>';
        }
    }

    echo '<br/>';
}

如果需要其他任何信息,请告诉我,我会把它丢进去.

解决方案

您可以进行对角线移动的次数仅限于必须横越行才能到达目的地的行数或列数.其他所有动作都可以向左/向右或向上/向下移动,并保持最短的距离.

也就是说,假设您知道单元格的行号和列号,我相信这将为您提供最短的距离:

$startCol = [column of starting cell];
$startRow = [row of starting cell];

$endCol = [column of end cell];
$endRow = [row of end cell];

$numMoves = 0;

$moveCol = 0;
$moveRow = 0;

/*
 * figure out which direction the end cell is, in relation to the
 * start cell.
 */

// end is to the right, so we need to add columns to the start
if( $startCol < $endCol ) {
    $moveCol = 1;
}
// end is to the left (or in the same column), so we need to subtract
// column from the start
else {
    $moveCol = -1;
}

// end is below the start, so we need to add rows
if( $startRow < $endRow ) {
    $moveRow = 1;
}
// end is above (or in the same row), so we need to subtract rows to the start
else {
    $moveRow = -1;
}

/*
 * now go diagnoal until you hit either the row or the column
 * that the end cell is in
 */

while( $startCol != $endCol && $startRow != $endRow ) {
    $startCol += $moveCol;
    $startRow += $moveRow;
    $numMoves++;
}

/* at this point, we're either in the same row or the same column
 * as our destination, so just move down that row or col until we
 * reach the destination
 */

// already at the destination, don't do anything
if( $startCol == $endCol && $startRow == $endRow ) {
}
// in the same column, so move up/down rows
else if( $startCol == $endCol ) {
    while( $startRow != $endRow ) {
        $startRow += $moveRow;
        $numMoves++;
    }
}
// in the same row, so move left/right cols
else {
    while( $startCol != $endCol ) {
        $startCol += $moveCol;
        $numMoves++;
    }
}

echo "min moves: $numMoves";

在此示例中,只要您假设开始和结束坐标实际上都在网格内,就不需要了解网格.

edit: Diagonal movement is allowed

I have a 5x5 Grid (just temp. to make it easier on myself though will grow to 30x30 and larger) and I'm trying to determine a grid count between 2 grids, however, it's doing my head in and I was hoping maybe someone can point me in the right direction. What I'm trying to achieve is basically a user chooses 2 grids i.e. 3004 and 3017 it should then find the shortest route and count the grids. For instance, the grid count between 3004 and 3017 should be 4, the grid count between 3001 and 3005 should be 5, the grid count between 3001 and 3017 should be 4, the grid count between 3001 and 3002 should be 2, etc.

The Grid:

------------------------------------
| 3001 | 3002 | 3003 | 3004 | 3005 |
------------------------------------
| 3006 | 3007 | 3008 | 3009 | 3010 |
------------------------------------
| 3011 | 3012 | 3013 | 3014 | 3015 |
------------------------------------
| 3016 | 3017 | 3018 | 3019 | 3020 |
------------------------------------
| 3021 | 3022 | 3023 | 3024 | 3025 |
------------------------------------

My array is structured in the following way:

$grids = array(
    1 => array(
        1 => 3001,
        2 => 3002,
        3 => 3003,
        4 => 3004,
        5 => 3005
    ),
    2 => array(
        1 => 3006,
        2 => 3007,
        3 => 3008,
        4 => 3009,
        5 => 3010
    ),
    3 => array(
        1 => 3011,
        2 => 3012,
        3 => 3013,
        4 => 3014,
        5 => 3015
    ),
    4 => array(
        1 => 3016,
        2 => 3017,
        3 => 3018,
        4 => 3019,
        5 => 3020
    ),
    5 => array(
        1 => 3021,
        2 => 3022,
        3 => 3023,
        4 => 3024,
        5 => 3025
    ),
);

What I have tried:

I realized I could use the good old Hypotenuse a2 + b2 = c2

That worked pretty good for a few examples, but, not everytime. For example, if I plugged in 3004 and 3017 the grid count should be 4, but, it spits out 5 or if I plugged in 3001 and 3025 the grid count would be 7, which is outside of the grid itself. I do understand why those results are coming up so I wanted to check if there is a way to improve the formula to make it work somehow?

This issue is killing me as I'm so close to to a solution I can taste it.

A big thank you for all the help in advance!

My current code: (please excuse the messiness)

<style>
.grid {
    display: inline-block;
    line-height: 50px; padding-left: 10px; padding-right: 10px;
    border:1px solid black;
}
.grid.active {
    background: red;
}
</style>
<?php

/*
3001  3002  3003  3004  3005
3006  3007  3008  3009  3010
3011  3012  3013  3014  3015
3016  3017  3018  3019  3020
3021  3022  3023  3024  3025
*/

$from = 3001;
$to   = 3025;

$grids = array(
    1 => array(
        1 => 3001,
        2 => 3002,
        3 => 3003,
        4 => 3004,
        5 => 3005
    ),
    2 => array(
        1 => 3006,
        2 => 3007,
        3 => 3008,
        4 => 3009,
        5 => 3010
    ),
    3 => array(
        1 => 3011,
        2 => 3012,
        3 => 3013,
        4 => 3014,
        5 => 3015
    ),
    4 => array(
        1 => 3016,
        2 => 3017,
        3 => 3018,
        4 => 3019,
        5 => 3020
    ),
    5 => array(
        1 => 3021,
        2 => 3022,
        3 => 3023,
        4 => 3024,
        5 => 3025
    ),
);

$from_cells = 1;
$from_rows  = 1;

foreach ( $grids as $y => $xs )
{
    $from_cells = 1;

    foreach ( $xs as $x => $postcode )
    {
        if ( $postcode == $from )
        {
            break 2;
        }
        else
        {
            $from_cells++;
        }
    }

    $from_rows++;
}

$to_cells = 1;
$to_rows  = 1;

foreach ( $grids as $y => $xs )
{
    $to_cells = 1;

    foreach ( $xs as $x => $postcode )
    {
        if ( $postcode == $to )
        {
            break 2;
        }
        else
        {
            $to_cells++;
        }
    }

    $to_rows++;
}

echo "From<hr/>X: $from_cells | Y: $from_rows<br/><hr/>To<hr/>X: $to_cells | Y: $to_rows";

$leg1 = 0;
$leg2 = 0;

$cell_short = ($from_cells < $to_cells) ? $from_cells : $to_cells;
$cell_long  = ($from_cells > $to_cells) ? $from_cells : $to_cells;

for ( $i=$cell_short; $i <= $cell_long; $i++ )
{
    $leg1 = $i;
}

$row_short = ($from_rows < $to_rows) ? $from_rows : $to_rows;
$row_long  = ($from_rows > $to_rows) ? $from_rows : $to_rows;

for ( $i=$row_short; $i <= $row_long; $i++ )
{
    $leg2 = $i;
}

echo "<hr/>Length: $leg1<br/>Height: $leg2";

$grid_count = pow($leg1,2) + pow($leg2,2);
$grid_count = floor(sqrt($grid_count));

echo "<hr/>Grids: $grid_count<hr/>";

foreach ( $grids as $y => $xs )
{
    foreach ( $xs as $x => $postcode )
    {
        if ( $postcode == $from or $postcode == $to )
        {
            echo '<div class="grid active">'.$postcode.'</div>';
        }
        else
        {
            echo '<div class="grid">'.$postcode.'</div>';
        }
    }

    echo '<br/>';
}

If any other information is needed please let me know and I'll throw it in.

解决方案

The number of diagonal moves you can make is limited to the number of either rows or columns you have to traverse to get to your destination. All other moves can be left/right or up/down and will preserve the shortest distance.

That said, and assuming you know the row and col numbers for your cells, I believe this will give you your shortest distance:

$startCol = [column of starting cell];
$startRow = [row of starting cell];

$endCol = [column of end cell];
$endRow = [row of end cell];

$numMoves = 0;

$moveCol = 0;
$moveRow = 0;

/*
 * figure out which direction the end cell is, in relation to the
 * start cell.
 */

// end is to the right, so we need to add columns to the start
if( $startCol < $endCol ) {
    $moveCol = 1;
}
// end is to the left (or in the same column), so we need to subtract
// column from the start
else {
    $moveCol = -1;
}

// end is below the start, so we need to add rows
if( $startRow < $endRow ) {
    $moveRow = 1;
}
// end is above (or in the same row), so we need to subtract rows to the start
else {
    $moveRow = -1;
}

/*
 * now go diagnoal until you hit either the row or the column
 * that the end cell is in
 */

while( $startCol != $endCol && $startRow != $endRow ) {
    $startCol += $moveCol;
    $startRow += $moveRow;
    $numMoves++;
}

/* at this point, we're either in the same row or the same column
 * as our destination, so just move down that row or col until we
 * reach the destination
 */

// already at the destination, don't do anything
if( $startCol == $endCol && $startRow == $endRow ) {
}
// in the same column, so move up/down rows
else if( $startCol == $endCol ) {
    while( $startRow != $endRow ) {
        $startRow += $moveRow;
        $numMoves++;
    }
}
// in the same row, so move left/right cols
else {
    while( $startCol != $endCol ) {
        $startCol += $moveCol;
        $numMoves++;
    }
}

echo "min moves: $numMoves";

In this example, you don't need any knowledge of the grid, as long as you assume the start and end co-ordinates are actually within the grid.

这篇关于PHP:确定2个网格之间的网格数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆