2016-12-19 8 views
3

は、元の配列があると思います。PHPで配列を線形分布から正規分布にソートする方法は?

$array[] = array('name' => 'a', 'code'=>1); 
$array[] = array('name' => 'b', 'code'=>2); 
$array[] = array('name' => 'c', 'code'=>3); 
$array[] = array('name' => 'd', 'code'=>4); 
$array[] = array('name' => 'e', 'code'=>5); 
$array[] = array('name' => 'f', 'code'=>6); 
$array[] = array('name' => 'g', 'code'=>7); 
$array[] = array('name' => 'h', 'code'=>8); 
$array[] = array('name' => 'i', 'code'=>9); 

それはcodeによってリニアソートだし、どのようにこのようなcodeによって正規分布としてそれを並べ替えることができます。

$array[] = array('name' => 'a', 'code'=>1); 
$array[] = array('name' => 'c', 'code'=>3); 
$array[] = array('name' => 'e', 'code'=>5); 
$array[] = array('name' => 'g', 'code'=>7); 
$array[] = array('name' => 'i', 'code'=>9); 
$array[] = array('name' => 'h', 'code'=>8); 
$array[] = array('name' => 'f', 'code'=>6); 
$array[] = array('name' => 'd', 'code'=>4); 
$array[] = array('name' => 'b', 'code'=>2); 

たぶんusortを助けることができますか?


UPDATE

私はNormal Distributionを言うとき、私は下の画像のような意味で、最大数は真ん中にある:

normal distribution

そして、いくつかのCOMMONはそこにありませんメソッドはそれを行うことができますか?たぶん今度はの「普通の分布」と次回はソートのための別のルールが必要ですか? usortのような方法がありますか?

答えて

3

これが実行されます。以下のコードは、配列を2つの新しい配列に分割します。偶数のものは、最初に新しい要素を持つ配列に追加されます。奇数のものは、他の新しい配列の最後に追加されます。次に、それらをマージします。末端から配列アイテム上

$r = []; 
for ($i = count($array) - 1; $i >= 0; --$i) { 
    if ($i % 2) { 
    $r []= $array[$i]; 
    } else { 
    array_unshift($r, $array[$i]); 
    } 
} 

コードの反復を次のよう

$array = []; 

$array[] = array('name' => 'a', 'code'=>1); 
$array[] = array('name' => 'b', 'code'=>2); 
$array[] = array('name' => 'c', 'code'=>3); 
$array[] = array('name' => 'd', 'code'=>4); 
$array[] = array('name' => 'e', 'code'=>5); 
$array[] = array('name' => 'f', 'code'=>6); 
$array[] = array('name' => 'g', 'code'=>7); 
$array[] = array('name' => 'h', 'code'=>8); 
$array[] = array('name' => 'i', 'code'=>9); 



$array1 = []; 
$array2 = []; 


foreach ($array as $item) { 
    $element = array_shift($array); 

    if ($element['code'] % 2 == 0) { 
     array_unshift($array1, $element); 
    } else { 
     $array2[] = $element; 
    } 
} 

$array = array_merge($array2, $array1); 
1

所望のアレイがO(N)に内蔵することができます。奇数インデックスの項目($i % 2が0でない場合)が$rの最後に追加され、偶数インデックスの項目が配列の先頭に追加されます。


codeによってリニアソートだ、どのように上記のコードは、所望の配列を生成するが、正規分布にソートされていないアイテムうcode

により正規分布としてそれを並べ替えることができによってcodecodeによって正規分布の項目をソートするために、あなたは次のように正規分布のprobability densityを計算する必要があります:

mean = 5 
i: 9 
a: 1 
b: 2 
h: 8 
c: 3 
g: 7 
d: 4 
f: 6 
e: 5 

/** 
* @param float $x the value 
* @param float $mean Mean or expectation of the distribution (median) 
* @param float $stddev Standard deviation 
* @return float Probability density of the normal distribution 
*/ 
function dens_normal($x, $mean, $stddev) { 
    $z = ($x - $mean)/$stddev; 
    return (1/($stddev * sqrt(2.0 * pi()))) * exp(-0.5 * $z * $z); 
} 

// Calculate the mean code value 
$mean = 0; 
foreach ($array as $e) { $mean += $e['code']; } 
$mean /= count($array); 
echo "mean = $mean\n"; 

// Standard deviation for the code value 
$stddev = 1; 

usort($array, function ($a, $b) use ($mean, $stddev) { 
    $da = dens_normal($a['code'], $mean, $stddev); 
    $db = dens_normal($b['code'], $mean, $stddev); 
    return $da == $db ? 0 : ($da < $db ? -1 : 1); 
}); 


foreach ($array as $e) { 
    printf("%s: %d\n", $e['name'], $e['code']); 
} 

出力大きな違い平均値(5)の値が小さいほど、配列インデックスは低くなります。言い換えれば、配列は平均値(5)への「近接度」によって降順でソートされます。

+0

「正規分布」の誤解を指摘していただきありがとうございます。あなたの答えが今のところ最高です。しかし、アップデートで説明されているようないくつかの 'common'メソッドがあれば? – KaKa

関連する問題