PHP:确定2个网格之间的网格数 [英] PHP: Determining Grid Count Between 2 Grids
问题描述
允许对角移动
我有一个5x5的网格(虽然会逐渐增加到30x30或更大,只是为了使自己更容易一些而已,但我正在尝试确定2个网格之间的网格数,但是,这是我的努力,希望有人可以指出我正确的方向.我想要实现的基本上是用户选择2个网格,即3004
和3017
,然后应该找到最短的路线并计算网格.例如,3004
和3017
之间的网格数应为4
,3001
和3005
之间的网格数应为5
,3001
和3017
之间的网格数应为4
,3001
和3002
之间的网格数应为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 >
在几个示例中,效果很好,但并非每次都如此.例如,如果我插入3004
和3017
,则网格数应为4
,但是,它会吐出5
,或者如果我插入3001
和3025
,则网格数应为
这个问题正在使我丧命,因为我已经接近可以品尝到的解决方案了.
非常感谢您预先提供的所有帮助!
我当前的代码:(请谅解)
<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屋!