2010-08-11 11 views
5

Staram się wiedzieć, od czego zacząć, próbując przydzielić rangi do wartości liczbowych w tablicy, gdy są więzy. Tak więc, na przykład, muszę włączyć tablicę tak:Jak przypisać numer rangowy do tablicy, gdy istnieją więzy

myarray = (4,76,34,13,34) 

do innej tablicy jak:

myarray2 = (1,5,3.5,2,3.5) 

Zasadniczo, gdy taka sama liczba występuje więcej niż jeden raz w tablicy, przypisany ranking do tych liczb jest średnią z rankingów. Tak więc, zamiast dwóch 34, które zajęły 3 i 4 miejsce, obaj otrzymują przypisane 3.5. Podobnie, gdyby było 3 kopie 34, 3 przydzielone rangi byłyby podzielone przez 3. Każda pomoc byłaby bardzo cenna!

Dziękujemy,

Adam

+1

I nie znaleźliśmy żadnego konkretnego schemat pomiędzy dwiema formami macierzy. – Sarfraz

+0

możesz wyjaśnić więcej? – shox

+0

To bardzo nietypowa metoda obsługi krawatów. –

Odpowiedz

2

Bawiłem się z tym!

function rank($input) 
{ 
    $output = array(); 
    $ranking = $input; sort($ranking); $ranking = array_flip($ranking); 
    $last_val = -1; 
    foreach($ranking as $key => $val){ 
    $repetitions = ($val-$last_val-1); 
    $last_val = $val; 
    if($repetitions) {  
     $ranking[$key] = (($val*($repetitions+1))-($repetitions+1)*(($repetitions)/2))/($repetitions+1)+1 ; 
    } else { 
     $ranking[$key] = $val+1; 
    } 
    } 
    foreach($input as $key => $val){ 
    $output[$key] = $ranking[$val]; 
    } 
    return $output; 
} 

Używaj go tak: wyjście

$a = array(4,76,34,13,34);  
$c = rank($a); 
print_r($c); 

będzie:

Array 
(
    [0] => 1 
    [1] => 5 
    [2] => 3.5 
    [3] => 2 
    [4] => 3.5 
) 

wich jest taka sama, jak:

Array(1, 5, 3.5, 2, 3.5) 

zgodnie z oczekiwaniami!

1

Zakładam, trzeba także obsługiwać przypadki, w których znajdują się trzy lub cztery lub n wartości wiązane na tej samej rangi.

nie jestem PHP guru, ale tutaj jest podejście (pseudo kod) do definiowania funkcji rank:

define a = original array 
define s = a.Sorted 
define rank(n) = (s.FirstIndexOf(n) + s.LastIndexOf(n))/2 

może trzeba pracować kilka przykładów na papierze, aby przekonać się, że to działa nawet na trzy i więcej; jest zależne od s sortowane tak, że duplikaty sąsiadują ze sobą.

+1

W jaki sposób uzyskuje się wartości s z powrotem w kolejności w tablicy wejściowej? – aaronasterling

+0

Nie przywracasz 's' do porządku, nie musisz tego robić (i tak czy inaczej nie mógłbyś). 'a' to oryginalna tablica, w oryginalnej kolejności. 's' jest * kopią *. – Bevan

+0

czy zakłada się, że tablica ma wartość 0 lub 1-index? – Tom

2

Oto jeden sposób, aby to zrobić.

<?php 
$myarray  = array(4,76,34,13,34); 

$sorted_array = $myarray; 
$grouped_array = array(); 
sort($sorted_array); 
foreach ($sorted_array as $rank => $entry) { 
    // Initialize the entry if it doesn't already exist 
    if (empty($grouped_array[$entry])) { 
     $grouped_array[$entry]['count'] = 1.0; 
     $grouped_array[$entry]['total'] = $rank + 1; // Account for 0-based array 
    } else { 
     $grouped_array[$entry]['count'] += 1.0; 
     $grouped_array[$entry]['total'] += $rank + 1; // Account for 0-based array 
    } 
} 
$myarray2 = array(); 
foreach ($myarray as $entry) { 
    // Get the average 
    $myarray2[] = $grouped_array[$entry]['total']/$grouped_array[$entry]['count']; 
} 
0

przyjętego rozwiązania (i inni też) wydają się być o wiele bardziej skomplikowana niż muszą być:

function Rank($data) { 
    $count = 0; 
    $unique = $data; sort($unique); 
    $unique = array_count_values($unique); 

    foreach ($unique as $key => $frequency) { 
     foreach (range(1, $frequency) as $i) { 
      $unique[$key] += $count++; 
     } 

     $unique[$key] /= $frequency; 
    } 

    foreach ($data as $key => $value) { 
     $data[$key] = $unique[$value]; 
    } 

    return $data; 
} 

Przykład (demo):

print_r(Rank(array(4, 76, 34, 13, 34))); // 1; 5; 3.5; 2; 3.5 
print_r(Rank(array(4, 76, 34, 13, 34, 34))); // 1; 6; 4; 2; 4; 4 
Powiązane problemy