2017-02-10 34 views
0

晚上好球員,使用array_splice導致「未定義偏移」誤差

目前正在對一段代碼,如果條件滿足,將被刪除陣列。在使用array_unset嘗試之後,我決定使用array_splice不破壞id結構。不幸的是我有同樣的問題:

E_NOTICE : type 8 -- Undefined offset: 5 -- at line 59 
E_NOTICE : type 8 -- Undefined offset: 5 -- at line 60 

偏移隊伍從5到2

說明:要理解我在做什麼在這裏,我給一個簡短的解釋。使用給定的x座標和y座標,我的小程序應該遍歷數組元素以查找離開始城鎮最近的城市。最近的點將成爲新的起點,並從城市陣列中移除,因爲它已經被訪問過。整個過程再次開始,直到城市陣列中沒有其他元素。這就像旅行推銷員問題。

現在我想解決它,但我不知道如何也不明白這個問題。我讀了關於使用array_values,它不起作用。

$cities = array 
    (
    (0) => Array(
     ('city') => 'San Francisco', 
     ('x_cord') => '22', 
     ('y_cord') => '28', 
    ), 
    (1) => Array(
     ('city') => 'Oakland', 
     ('x_cord') => '15', 
     ('y_cord') => '13', 
    ), 
    (2) => Array(
     ('city') => 'Stanford', 
     ('x_cord') => '5', 
     ('y_cord') => '2', 
    ), 
    (3) => Array(
     ('city') => 'Palo Alto', 
     ('x_cord') => '17', 
     ('y_cord') => '15', 
    ), 
    (4) => Array(
     ('city') => 'San Jose', 
     ('x_cord') => '5', 
     ('y_cord') => '2', 
    ), 
    (5) => Array(
     ('city') => 'Marin', 
     ('x_cord') => '22', 
     ('y_cord') => '28', 
    ), 
    (6) => Array(
     ('city') => 'Sacramento', 
     ('x_cord') => '30', 
     ('y_cord') => '40', 
    ) 
);  




$curCit = "San Francisco"; 
$key = array_search('Oakland', array_column($cities, 'city')); 
$curX = $cities[$key]['x_cord']; //3; 
$curY = $cities[$key]['y_cord']; //4; 
$hv = 0; 
$distance = 0; 
$row_city = 0; 

$way = array(); 
$counter = count($cities); 
while ($counter>0) { 

     for ($i = 5; $i >= 0; $i--) { 
      global ${"value_" . $i}; 
      //${"value_" . $i} = $cities[$i][1]+$cities[$i][2]; 
      ${"value_" . $i . "x"} = $curX - $cities[$i]['x_cord']; 
      ${"value_" . $i . "y"} = $curY - $cities[$i]['y_cord']; 
      ${"value_" . $i} = sqrt(${"value_" . $i . "x"}*${"value_" . $i . "x"} + ${"value_" . $i . "y"}*${"value_" . $i . "y"}); 

      if ($hv == 0) { 
       //global $hv; 
       $hv = ${"value_" . $i}; 

      } 
      elseif ($hv > 0) { 



         if (${"value_" . $i}<$hv) { 
         //global $hv; 
         $hv = ${"value_" . $i}; 
         $distance = $distance + $hv; 
         $row_city = $i; 
         $curX = $cities[$i]['x_cord']; //3; 
         $curY = $cities[$i]['y_cord']; //4; 


           $newdata = array (
             'next_city' => $cities[$i]['city'], 
             'nxt_cty_xcord' => $cities[$i]['x_cord'], 
             'nxt_cty_ycord' => $cities[$i]['y_cord'], 
             'distance' => ${"value_" . $i} 
            ); 
          //array_push($way,$newdata); 
     array_push($way,$newdata); 
     array_splice($cities, $i); 
     $cities = array_values($cities); 

         } //end 2nd if-clause 

      echo number_format(${"value_" . $i},2); 
      echo " "; 
      echo "HV "; 
      echo number_format($hv,2); 
      echo "<br>"; 
      $hv = 0; 

     } //end 1st if-clause 
     } //end for-clause 



     $counter--; 
} //end while-loop 
print_r($cities); 
echo "<br>"; 
print_r($way); 

該代碼是不完美的,因爲我仍然工作。但是從城市多維數組中刪除數組元素的問題阻止了我。

任何人都可以提供幫助和建議嗎? 如果你喜歡推薦array_values,那麼請嘗試一下並且可能犯了一個錯誤。

在此先感謝。

編輯:雖然如果我把array_splice放在我賦值給的變量後面會是一個解決方案。

+0

推薦閱讀:http://stackoverflow.com/help/mcve – wogsland

+0

的問題是,你想從$城市的讀取元件在行'$ {「value_」處。 $ i。 「x」} = $ curX - $ cities [$ i] ['x_cord'];''$ {「value_」。 $ i。 「y」} = $ curY - $ cities [$ i] ['y_cord'];'目前不存在,因爲它與'array_splice($ cities,$ i);'拼接在一起。試着解釋你想要達到什麼目標,因爲必須有比這一堆IF更好的方法...... –

+0

@HonzaRydrych:在帖子中增加了一個額外的解釋。如果我需要改進解釋,請告訴我。也許它還不夠精確。 是的,這是不幸的問題,但認爲,如果在腳本從第1行到第xy個「正在運行」時將值賦予變量,則將剪接定位。 wogsland:對不起= ^} – nucky

回答

0

我試圖根據您的描述儘可能簡化您的代碼。如果有什麼不清楚的地方,請不要猶豫。我忽略了結果中的'next_city'項,因爲它似乎沒有必要(由於下一項中的數據相同),但代碼可以很容易地更改。

  • 嘗試使用可變的變量$ {XY}只有當它是必要的,它的可讀性變差,即使你一年或兩年:-)
  • 後:

    值得檢討你的代碼後提那些事

  • 當你處理具有不明索引的迭代(例如數組)時,使用foreach循環而不是for。從數組中刪除項目時,您將不會遇到未定義索引的問題。

最後的代碼(沒有數組定義):

//for debugging 
//var_dump($cities); 

$startCity = "San Francisco"; 

$nearestCityIndex = array_search($startCity, array_column($cities, 'city')); 
$hv = null; 
$counter = count($cities); 
for($c=0; $c < $counter; $c++) { 
    //add new item to the route plan array 
    $route[] = array_merge(
     $cities[$nearestCityIndex], 
     array('distanceFromPrevious' => $hv) 
    ); 

    //remove already planned city from source array 
    unset($cities[$nearestCityIndex]); 

    //get last one from already planned cities 
    $lastItem = $route[count($route)-1]; 

    $hv = 99999; 
    //loop through remaining cities to get shortest possible distance last planned city 
    foreach($cities as $key => $item) { 
     $tmpDist = sqrt(pow($lastItem['x_cord'] - $item['x_cord'],2) + pow($lastItem['y_cord'] - $item['y_cord'], 2)); 
     if ($hv >= $tmpDist) { 
      $hv = $tmpDist; 
      $nearestCityIndex = $key; 
     } 
    } 
} 

//for debugging 
//echo "<br><br>"; 
//var_dump($route); 
+0

這個答案有用或需要任何解釋嗎? –

+0

感謝您的回答。理解你的解決方案需要一段時間,但這是一個很好的解決方案,簡單而簡短。你的代碼教會了我很多。 – nucky