2015-03-02 71 views
3

我的結果數組在這裏發生了什麼?我預計結果數組的大小等於輸入數組,但缺少3個條目..他們去了哪裏?他們沒有去$ RET,因爲他們應該..我的數組發生了什麼?物品消失

代碼:

<?php 
init(); 
$list_xy = array(
    0 => array(
     'id' => '308', 
     'x' => '37', 
     'y' => '63' 
    ), 
    1 => array(
     'id' => '963', 
     'x' => '38', 
     'y' => '134' 
    ), 
    2 => array(
     'id' => '385', 
     'x' => '39', 
     'y' => '132' 
    ), 
    3 => array(
     'id' => '1231', 
     'x' => '50', 
     'y' => '199' 
    ), 
    4 => array(
     'id' => '788', 
     'x' => '51', 
     'y' => '59' 
    ), 
    5 => array(
     'id' => '1151', 
     'x' => '53', 
     'y' => '61' 
    ), 
    6 => array(
     'id' => '671', 
     'x' => '55', 
     'y' => '60' 
    ), 
    7 => array(
     'id' => '1487', 
     'x' => '55', 
     'y' => '55' 
    ) 
); 
$sorted_list_xy = sort_by_xy_distance($list_xy); 
$sorted_list_xy_size = count($sorted_list_xy, COUNT_NORMAL); 
$list_xy_size = count($list_xy, COUNT_NORMAL); 
var_dump($sorted_list_xy_size == $list_xy_size ? "looks right" : "something is wrong", $sorted_list_xy_size, $list_xy_size); 
die("died"); 


function sort_by_xy_distance($input_list) 
{ 
    $ret = array(); 
    $a = $input_list[0]; 
    array_push($ret, $input_list[0]); 
    $input_list[0] = null; 
    $i = 1; 
    for ($i = 1; $i < count($input_list); ++$i) { 
     if ($input_list[$i] == null) { 
      echo 'already added to list..'; 
      continue; 
     } 
     $ii = 1; 
     $tmpdistance = 0; 
     $nearest = array(
      'index' => -1, 
      'distance' => PHP_INT_MAX 
     ); 
     for ($ii = 1; $ii < count($input_list); ++$ii) { 
      if ($input_list[$ii] == null || $ii == $i) { 
       //echo 'already added to list..'; 
       continue; 
      } 
      $tmpdistance = abs($input_list[$ii]['x'] - $a['x']) + abs($input_list[$ii]['y'] - $a['y']); 
      if ($tmpdistance < $nearest['distance']) { 
       $nearest['index'] = $ii; 
       $nearest['distance'] = $tmpdistance; 
      } 
     } 
     assert($nearest['index'] != -1); 
     array_push($ret, $input_list[$nearest['index']]); 
     $a = $input_list[$nearest['index']]; 
     $input_list[$nearest['index']] = null; 
    } 
    return $ret; 
} 





function init() 
{ 
    error_reporting(E_ALL); 
    set_error_handler("exception_error_handler"); 
} 
function exception_error_handler($errno, $errstr, $errfile, $errline) 
{ 
    if (!(error_reporting() & $errno)) { 
     // This error code is not included in error_reporting 
     return; 
    } 
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline); 
} 

輸出:

已經加入到list..already加入list..already加入 list..string(18) 「什麼是錯的」 INT(5)INT(8)死亡

預期輸出:(東西類似)

已經加入到list..already加入list..already加入 list..string(11) 「期待權」 INT(8)INT(8)死亡

我的預期名單轉向到: 一個列表,其中的差異在未來的[X] [Y]是儘量少,這將是:

array(8) { 
    [0]=> 
    array(3) { 
    ["id"]=> 
    string(3) "308" 
    ["x"]=> 
    string(2) "37" 
    ["y"]=> 
    string(2) "63" 
    } 
    [1]=> 
    array(3) { 
    ["id"]=> 
    string(3) "788" 
    ["x"]=> 
    string(2) "51" 
    ["y"]=> 
    string(2) "59" 
    } 
    [2]=> 
    array(3) { 
    ["id"]=> 
    string(4) "1151" 
    ["x"]=> 
    string(2) "53" 
    ["y"]=> 
    string(2) "61" 
    } 
    [3]=> 
    array(3) { 
    ["id"]=> 
    string(3) "671" 
    ["x"]=> 
    string(2) "55" 
    ["y"]=> 
    string(2) "60" 
    } 
    [4]=> 
    array(3) { 
    ["id"]=> 
    string(4) "1487" 
    ["x"]=> 
    string(2) "55" 
    ["y"]=> 
    string(2) "55" 
    } 
    [5]=> 
    array(3) { 
    ["id"]=> 
    string(3) "385" 
    ["x"]=> 
    string(2) "39" 
    ["y"]=> 
    string(3) "132" 
    } 
    [6]=> 
    array(3) { 
    ["id"]=> 
    string(3) "963" 
    ["x"]=> 
    string(2) "38" 
    ["y"]=> 
    string(3) "134" 
    } 
    [7]=> 
    array(3) { 
    ["id"]=> 
    string(4) "1231" 
    ["x"]=> 
    string(2) "50" 
    ["y"]=> 
    string(3) "199" 
    } 
} 

我在做圖形說明吮吸,但生病給它去吧。 這是我的地圖: map http://imagizer.imageshack.us/a/img633/3521/E0HGRe.png

我需要訪問所有的黑點。 這是我目前的路徑: enter image description here

這條路不是很最優.. 這裏的路上,我想: enter image description here

,這就是分頁功能時,試圖找到,最短路徑訪問所有的黑點。

+0

我讀了很多程序代碼。但是,如果有'空格'將長字符串分解爲「令牌」,則可以更容易。你提供了很多代碼。我可以建議你按照一些容易閱讀的標準格式化它嗎?即[本指南的目的是在掃描來自不同作者的代碼時減少認知摩擦。它通過枚舉一組共享的規則和期望來說明如何格式化PHP代碼](http://www.php-fig.org/psr/psr-2/)。事物之間的空間是'好'的。人們閱讀和編寫代碼 - 讓他們很容易理解你的代碼? – 2015-03-02 16:56:18

+0

呵呵,實際上stackoverflow不允許我用空白換行符結束代碼:p ..無論如何,用PEAR風格通過phpformatter.com運行它,它現在看起來更好嗎? :o – hanshenrik 2015-03-02 17:02:34

+0

感謝那:-) – 2015-03-02 17:04:39

回答

0

距離計算你應該使用畢達哥拉斯定理(或只是hypot,像提到@prodigitalson)。對於地理座標,您可以使用:http://www.movable-type.co.uk/scripts/latlong.html

讓我們來修復您的代碼。第一個循環的每一步都應該從輸入值中取一個值並將其放入結果中。但它在內部仍在繼續,因此第一個循環的一些步驟不會完成他們的工作。嘗試刪除第一個繼續。

$list_xy = array(
    0 => array(
     'id' => '308', 
     'x' => '37', 
     'y' => '63' 
    ), 
    1 => array(
     'id' => '963', 
     'x' => '38', 
     'y' => '134' 
    ), 
    2 => array(
     'id' => '385', 
     'x' => '39', 
     'y' => '132' 
    ), 
    3 => array(
     'id' => '1231', 
     'x' => '50', 
     'y' => '199' 
    ), 
    4 => array(
     'id' => '788', 
     'x' => '51', 
     'y' => '59' 
    ), 
    5 => array(
     'id' => '1151', 
     'x' => '53', 
     'y' => '61' 
    ), 
    6 => array(
     'id' => '671', 
     'x' => '55', 
     'y' => '60' 
    ), 
    7 => array(
     'id' => '1487', 
     'x' => '55', 
     'y' => '55' 
    ) 
); 
$sorted_list_xy = sort_by_xy_distance($list_xy); 
$sorted_list_xy_size = count($sorted_list_xy, COUNT_NORMAL); 
$list_xy_size = count($list_xy, COUNT_NORMAL); 
var_dump($sorted_list_xy_size == $list_xy_size ? "looks right" : "something is wrong", $sorted_list_xy_size, $list_xy_size); 
die("died"); 

function sort_by_xy_distance($input_list) 
{ 
    $ret = array(); 
    $a = $input_list[0]; 
    array_push($ret, $input_list[0]); 
    $input_list[0] = null; 
    $i = 1; 
    for ($i = 1; $i < count($input_list); ++$i) { 
//               up here 
//  if ($input_list[$i] == null) { 
//   echo 'already added to list..'; 
//   continue; 
//  } 
     $ii = 1; 
     $tmpdistance = 0; 
     $nearest = array(
      'index' => -1, 
      'distance' => PHP_INT_MAX 
     ); 
     for ($ii = 1; $ii < count($input_list); ++$ii) { 
      if ($input_list[$ii] == null || $ii == $i) { 
       //echo 'already added to list..'; 
       continue; 
      } 
      $tmpdistance = abs($input_list[$ii]['x'] - $a['x']) + abs($input_list[$ii]['y'] - $a['y']); 
      if ($tmpdistance < $nearest['distance']) { 
       $nearest['index'] = $ii; 
       $nearest['distance'] = $tmpdistance; 
      } 
     } 
     assert($nearest['index'] != -1); 
     array_push($ret, $input_list[$nearest['index']]); 
     $a = $input_list[$nearest['index']]; 
     $input_list[$nearest['index']] = null; 
    } 
    return $ret; 
} 
+0

這不是無用的。它更快。 它與c/C++一致,並且它比後增量使用更少的操作碼,並且不返回'old'值,只返回新值,所以我們不需要2個值(舊值AND新值,作爲後增加) 但不要拿我的話,它自己的基準:http://pastebin.com/raw.php?i=kvDpyNY3 我的輸出:最快的是前增量。 (...)的區別是:0.73859477043152秒。 - 運行4-5次,這是一致的,在我的服務器上,預計增量大約快0.7秒,達到1億。 – hanshenrik 2015-03-04 04:51:44

+0

所以,你應該改變你的array_push。 – sectus 2015-03-04 04:54:40

+0

@ hanshenrik,它會回答你的工作嗎? – sectus 2015-03-04 04:58:45