和風細雨

          世上本無難事,心以為難,斯乃真難。茍不存一難之見于心,則運用之術自出。

          使用LinkedHashMap進行分數排序

          分數排序的特殊問題

          在java中實現排序遠比C/C++簡單,我們只要讓集合中元素對應的類實現Comparable接口,然后調用Collections.sort();方法即可.
          這種方法對于排序存在許多相同元素的情況有些浪費,明顯即使值相等,兩個元素之間也要比較一下,這在現實中是沒有意義的.
          典型例子就是學生成績統計的問題,例如高考中,滿分是150,成千上萬的學生成績都在0-150之間,平均一個分數的人數成百上千,這時如果排序還用傳統方法明顯就浪費了.

          進一步思考

          成績既然有固定的分數等級,我們可以把相同等級的成績放在一起,以100分為滿分計,共分一百個等級,來一個成績就歸入固定的檔,要得到排序結果時可以從低檔取到高檔,取出來自然就是排序的結果.
          接下來是確定數據結構的問題,檔次-學生群這樣的自然是key-value結構,但Map中的Hashtable和HashMap都不能保持插入時的順序,雖然我們可以從固定的檔次取名單,但這樣略嫌不方便,我們需要更好的數據結構,它既以鍵值的形式存儲數據,又能保持插入時的順序.

          LinkedHashMap橫空出世

          LinkedHashMap正是這樣一個數據結構,它”在HashMap的基礎上增加了一個雙向鏈表,由此LinkedHashMap既能以哈希表的形式存儲數據,又能保持查詢時的順序.”
          下頁就是進行排序用的類,它在構造實例時先創建好分數檔次,加入學生成績時自動歸檔,要取出排序的學生的成績時只要按檔次輸出即可.

          ScoreSorter類

          package com.junglesong;

          import java.util.ArrayList;
          import java.util.Iterator;
          import java.util.LinkedHashMap;
          import java.util.List;
          import java.util.Map;

          /**
           * 學生分數排序類
           * 
          @author: sitinspring(junglesong@gmail.com)
           * @date: 2008-3-4
           
          */

          public class ScoreSorter{
              
          /**
               * 學生成績單
               
          */

              
          private Map<Integer,List<Student>> scoreSheet;
              
              
          /**
               * 滿分分數
               
          */

              
          private final int maxScore; 
              
              
          /**
               * 構造函數
               * 
          @param MaxScore: 滿分分數
               
          */

              
          public ScoreSorter(int MaxScore){
                  
          this.maxScore=MaxScore;
                  scoreSheet
          =new LinkedHashMap<Integer,List<Student>>();
                  
                  
          for(int i=0;i<=maxScore;i++){
                      List
          <Student> ls=new ArrayList<Student>();
                      scoreSheet.put(i, ls);
                  }

              }

              
              
          /**
               * 添加一個學生成績
               * 
          @param student
               
          */

              
          public void addStudent(Student student){
                  
          int score=student.getScore();
                  
          if(student.getScore()>maxScore){
                      
          return;
                  }

                  
                  List
          <Student> ls=scoreSheet.get(score);
                  ls.add(student);
              }

              
              
          /**
               * 得到從低到高的學生成績表
               *
               
          */

              @SuppressWarnings(
          "unchecked")
              
          public List<Student> getSortedScores(){
                  List
          <Student> retval=new ArrayList<Student>();
                  
                  Iterator it
          =scoreSheet.values().iterator();

                  
          while(it.hasNext()){
                      List
          <Student> ls=(List<Student>)it.next();
                      retval.addAll(ls);
                  }

                  
                  
          return retval;
              }

          }

          輔助類Student

          package com.junglesong;

          import java.util.ArrayList;
          import java.util.Collections;
          import java.util.List;
          import java.util.Random;

          public class Student implements Comparable{
              
          private String name;
              
          private int score;
              
              
          public Student(String name,int score){
                  
          this.name=name;
                  
          this.score=score;
              }

              
              
          public int compareTo(Object obj){
                  Student another
          =(Student)obj;        
                  
          return this.score-another.score;
              }

              
              
          public String toString(){
                  
          return "學生姓名="+name+" 分數="+score;
              }

              
          public String getName() {
                  
          return name;
              }


              
          public void setName(String name) {
                  
          this.name = name;
              }


              
          public int getScore() {
                  
          return score;
              }


              
          public void setScore(int score) {
                  
          this.score = score;
              }

              
              
          public static void main(String[] args){
                  
          //-----------老排序方案-----------
                  /*TimeTest oldSortTest=new TimeTest();
                  List<Student> scores=new ArrayList<Student>();
                  
                  Random random=new Random();
                  for(int i=0;i<100000;i++){
                      scores.add(new Student("學生"+i,random.nextInt(100)));
                  }
                  
                  Collections.sort(scores);
                  //for(Student student:scores){
                  //    System.out.println(student);
                  //}
                  oldSortTest.end("老排序方案耗時");
          */

                  
                  
          //-----------新排序方案-----------
                  TimeTest newSortTest=new TimeTest();
                  ScoreSorter sorter2
          =new ScoreSorter(100);
                  
                  Random random
          =new Random();
                  
          for(int i=0;i<1000;i++){
                      sorter2.addStudent(
          new Student("學生"+i,random.nextInt(100)));
                  }

                  
                  List
          <Student> ls=sorter2.getSortedScores();
                  
          //for(Student student:sorter2.getSortedScores()){
                  
          //    System.out.println(student);
                  
          //}
                  newSortTest.end("新排序方案耗時");    
              }

          }

           

          與傳統排序方案的比較

          在元素個數遠超等級個數即相同的元素很多時,這種方案在速度上稍高于傳統方案,節省的時間主要在不比較同等級元素上.
          這種方案能夠按檔次取出數據,這種優勢是傳統排序方案缺乏的.
          傳統方案普適性比此方案強.

          http://www.aygfsteel.com/Files/junglesong/ScoreSorter20080304222012.rar

          posted on 2008-03-04 21:06 和風細雨 閱讀(3997) 評論(1)  編輯  收藏 所屬分類: 算法

          評論

          # re: 使用LinkedHashMap進行分數排序 2008-08-02 11:28 天堂明月

          代碼我收下了,有機會一起討論技術吧  回復  更多評論   

          主站蜘蛛池模板: 阜宁县| 承德市| 晋州市| 开原市| 嘉祥县| 隆安县| 赤水市| 水城县| 甘泉县| 崇左市| 莒南县| 辉县市| 宁城县| 略阳县| 婺源县| 江源县| 子长县| 金寨县| 永胜县| 永嘉县| 通江县| 鄂托克前旗| 临澧县| 北票市| 闽清县| 潞西市| 孟连| 江源县| 贡嘎县| 娱乐| 天津市| 南昌县| 咸宁市| 衡山县| 宜兰市| 康平县| 清涧县| 西峡县| 江永县| 泰宁县| 甘肃省|