2011-05-28 38 views
5

我正在研究操縱大學生考試成績的數據庫。基本上,我正在從MySq數據庫中提取記錄,在任何給定時間創建一個課程。我想將排名最高的學生排在第一位。
下面是一個例子;如何排列重複值的數組值並跳過某些位置(如果有配合)?

Marks: 37, 92, 84, 83, 84, 65, 41, 38, 38, 84. 

所以我想捕獲mysql數據作爲單個數組。一旦我將數據存入數組,我應該爲每個學生指定一個位置,如1/10(數字1,92分),4/10等。現在問題是,如果有一條平行線,那麼下一個分數跳過一個位置,如果在一個位置有3個分數,則下一個分數跳過2個位置。所以上面的分數排名如下:

92 - 1 
84 - 2, 
84 - 2, 
84 - 2, 
83 - 5, 
65 - 6, 
41 - 7, 
38 - 8, 
38 - 8 , 
37 - 10 

分級系統需要的位置數(行列,如果你會)將保持不變,所以我們結束了10個職位在這個類,因爲位置3,4,5和9沒有任何乘客。 (填充每個數字的替代方案將只給我們8個位置!)

是否有可能(人類可能/ php可能)使用PHP對上述分數進行排序,以便它可以處理可能的關係,如4個分數在一個位置? SADLY,我不能想出一個功能來做到這一點。我需要一個PHP函數(或者什麼...... PHP),它將採用一個數組併產生如上所述的排名。

任何幫助將深受讚賞,但我想我可能會要求太多。如果可以用MySQL查詢數據而不用數組,那麼這也會有幫助!

回答

5

我假設成績已經按數據庫排序,否則使用sort($grades);

代碼:

$grades = array(92, 84, 84, 84, 83, 65, 41, 38, 38, 37); 
$occurrences = array_count_values($grades); 
$grades = array_unique($grades); 
foreach($grades as $grade) { 
    echo str_repeat($grade .' - '.($i+1).'<br>',$occurrences[$grade]); 
    $i += $occurrences[$grade]; 
} 

結果:

92 - 1 
84 - 2 
84 - 2 
84 - 2 
83 - 5 
65 - 6 
41 - 7 
38 - 8 
38 - 8 
37 - 10 

EDIT(響應於下面的討論)

顯然,在情況下,粘結髮生t最低分,
所有最低分的排名應該等於總分數。

代碼:

$grades = array(92, 84, 84, 84, 83, 65, 41, 38, 37, 37); 
$occurrences = array_count_values($grades); 
$grades = array_unique($grades); 
foreach($grades as $grade) { 
    if($grade == end($grades))$i += $occurrences[$grade]-1; 
    echo str_repeat($grade .' - '.($i+1).'<br>',$occurrences[$grade]); 
    $i += $occurrences[$grade]; 
} 

結果:

92 - 1 
84 - 2 
84 - 2 
84 - 2 
83 - 5 
65 - 6 
41 - 7 
38 - 8 
37 - 10 
37 - 10 
+0

這很有效,直到領帶結束。在這種情況下,分配給最後分數(相連的分數)的位置不會等於總分數。在上面的輸出中,你會看到分數爲37的數字爲10,這是不可能的,因爲它是最低分數,恰好是學生總數。然而,如果我們的平均分是37分(最低分)而不是38分,那麼最後兩個分數將被分配到9分而不是10分。我想有一個條件可以檢查一條平局是否涉及最低分,我是試圖添加這樣的條件 – Bululu 2011-05-28 20:36:11

+0

可以說我們有以下數組:'$ grades = array(92,84,84,84,83,65,41,38,37,37);''兩個'37'都出現在結果像'37 - 9',這是正確的,因爲第一個'37'實際上位於第九位置。總而言之,當平局發生在最低等級時,每個最低等級的等級等於最低等級的第一等級。在這種情況下'9'。對? – Anne 2011-05-28 21:06:39

+0

我認爲你的代碼應該解決問題。理由是確保最後的分數等於參加考試的學生人數,這有點有缺陷。如果平局發生在最後,最低分數將等於學生總數。如果最終的結果是不可能發生,並且IU同意這種觀點,如果第二最低得分手的位置可以說,例如9,則下一個得分手應該正確地獲得下一個位置,因爲沒有得分後那。同時非常感謝你的回答,你是天才! – Bululu 2011-05-28 21:50:35

1
$scores = array(92, 84, 84, 84, 83, 65, 41, 38, 38, 37); 
$ranks = array(1); 
for ($i = 1; $i < count($scores); $i++) 
{ 
    if ($scores[$i] != $scores[$i-1]) 
     $ranks[$i] = $i + 1; 
    else 
     $ranks[$i] = $ranks[$i-1]; 
} 
print_r($ranks); 
+0

@Bululu作爲stuken.yuri代碼的補充,我會指出,您可以從數據庫中獲取已經訂購的數據,因此您不必通過php函數對其進行排序。 – koressak 2011-05-28 17:37:28

+0

我能夠通過向查詢添加一些參數來從MySQL中獲取它。你是否可以像我的問題中所描述的那樣將數據操縱到一定程度?在領帶的情況下跳過一些位置?這是我認爲無法通過在查詢中添加DESC或ASC的順序來實現的要求。如果您能詳細說明如何使用查詢來實現這種高度的排名,我會很高興。 – Bululu 2011-05-28 19:46:04

+0

yuri,非常感謝你,你的解決方案也解決了這個問題。 – Bululu 2011-05-28 22:04:11

0

,我需要映射值的排名結束了。這種方法對於原始問題也可能更有效。

public static function getGrades($grades) 
{ 
    $occurrences = array_count_values($grades); 
    krsort($occurrences); 

    $position = 1; 
    foreach ($occurrences as $score => $count) { 
     $occurrences[$score] = $position; 
     $position += $count; 

    } 

    return $occurrences; 
} 

如果你的print_r對$出現你

Array 
(
    [92] => 1 
    [84] => 2 
    [83] => 5 
    [65] => 6 
    [41] => 7 
    [38] => 8 
    [37] => 10 
) 

在原有基礎上的答案,這樣的感謝!

相關問題