[英]Search array for similar objects
給定一個像這樣的數組:
$array = array(
0 => array (
0 => 35,
1 => 30,
2 => 39
),
1 => array (
0 => 20,
1 => 12,
2 => 5
),
...
n => array (
0 => 10,
1 => 15,
2 => 7
),
);
我需要在數組中找到更接近給定參數的條目
find($a, $b, $c) {
//return the closer entry to the input
}
對於更接近的條目,我的意思是條目與輸入中給出的值更接近,例如傳遞(19,13,3)它應該返回$ array [1]
我現在進行計算的方法是循環遍歷整個數組,保持從-1開始的變量$ distance和臨時$ result變量。 對於每個元素,我計算距離
$dist = abs( subarray[0] - $a ) + abs ( subarray[1] - $b ) + abs( subarray[2] - $c )
如果計算出的距離等於-1或低於循環外的變量$ distance,我將新距離分配給變量,並將相應的數組保存在$ result變量中。 在循環結束時,我最終得到了我需要的值。
此外,其中一個值可以為空:例如(19,13,false)仍應返回$ array [1],然后計算應忽略缺失參數 - 在這種情況下,距離計算為
$dist = abs( subarray[0] - $a ) + abs ( subarray[1] - $b );
忽略子陣列[2]和$ c的值。
問題是,即使我的代碼工作,也需要花費太多時間來執行,因為數組的大小很容易達到數十萬個元素。 我們仍然在談論毫秒,但由於各種原因,這仍然是不可接受的。 有沒有更有效的方法來進行此搜索以節省一些時間?
我基本上使用了一個鄰近的概念(每個數組的總距離較小)並返回。 代碼的制作方式可以在很多例程中得到很好的改進。
PS:我沒有使用高級功能或其他東西,因為你擔心性能問題。 這是我能在短時間內完成的最簡單的例行程序。
$array = array(
0 => array (
0 => 35,
1 => 30,
2 => 39
),
1 => array (
0 => 20,
1 => 12,
2 => 5
),
);
$user = array(19,13,3);
function find($referencial, $input){
$totalRef = count($referencial);
if (is_array($referencial)){
for ($i = 0; $i < $totalRef; $i++) {
if (is_array($referencial[$i])){
$totalSubRef = count($referencial[$i]);
$proximity = array();
for ($j = 0; $j < $totalSubRef; $j++) {
$proximity[$i] += abs($referencial[$i][$j] - $input[$j]);
}
if ($i > 0){
if ($maxProximity['distance'] > $proximity[$i]) {
$maxProximity['distance'] = $proximity[$i];
$maxProximity['index'] = $i;
}
} else {
$maxProximity['distance'] = $proximity[$i];
$maxProximity['index'] = $i;
}
}
}
return $maxProximity;
} else {
exit('Unexpected referencial. Must be an array.');
}
}
$found = find($array, $user);
print_r($found);
//Array ( [distance] => 4 [index] => 1 )
print_r($array[$found['index']]);
// Array ( [0] => 20 [1] => 12 [2] => 5 )
一個自定義功能 - 也許有一個更好的方法,但檢查出來:
簡而言之 :
搜索所有項目並以百分比查找它檢查的數字($ mArray [0 ... 3])與您給出的數字之間的差異($ mNumbersToFind [0 ... 3]。添加所有三個數字(每個元素)可能性 - 找到最大值 - 保持位置並返回數組。
$array = array(
array (
0 => 13,
1 => 15,
2 => 4
),
array (
0 => 20,
1 => 12,
2 => 5
),
array (
0 => 13,
1 => 3,
2 => 15
),
);
$mNumbersToFind = array(13,3,3);
$mFoundArray = find($mNumbersToFind, $array);
echo "mFinalArray : <pre>";
print_r($mFoundArray);
function find($mNumbersToFind, $mArray){
$mPossibilityMax = count($mNumbersToFind);
$mBiggestPossibilityElementPosition = 0;
$mBiggestPossibilityUntilNow = 0;
foreach($mArray as $index => $current){
$maxPossibility = 0;
foreach($current as $subindex => $subcurrent){
$mTempArray[$index][$subindex]['value'] = $subcurrent - $mNumbersToFind[$subindex];
$percentChange = (1 - $mTempArray[$index][$subindex]['value'] / $subcurrent) * 100;
$mTempArray[$index][$subindex]['possibility'] = $percentChange;
$maxPossibility += $percentChange/$mPossibilityMax;
}
$mTempArray[$index]['final_possibility'] = $maxPossibility;
if($maxPossibility > $mBiggestPossibilityUntilNow){
$mBiggestPossibilityUntilNow = $maxPossibility;
$mBiggestPossibilityElementPosition = $index;
}
}
echo "mTempArray : <pre>"; // Remove this - it's just for debug
print_r($mTempArray); // Remove this - it's just for debug
return $mArray[$mBiggestPossibilityElementPosition];
}
調試輸出($ mTempArray):
mTempArray :
Array
(
[0] => Array
(
[0] => Array
(
[value] => 0
[possibility] => 100
)
[1] => Array
(
[value] => 12
[possibility] => 20
)
[2] => Array
(
[value] => 1
[possibility] => 75
)
[final_possibility] => 65
)
[1] => Array
(
[0] => Array
(
[value] => 7
[possibility] => 65
)
[1] => Array
(
[value] => 9
[possibility] => 25
)
[2] => Array
(
[value] => 2
[possibility] => 60
)
[final_possibility] => 50
)
[2] => Array
(
[0] => Array
(
[value] => 0
[possibility] => 100
)
[1] => Array
(
[value] => 0
[possibility] => 100
)
[2] => Array
(
[value] => 12
[possibility] => 20
)
[final_possibility] => 73.333333333333
)
)
最終產出:
mFinalArray :
Array
(
[0] => 13
[1] => 3
[2] => 15
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.