2019独角兽企业重金招聘Python工程师标准>>>
举例见:
package com.mytest;
import java.math.RoundingMode;
import java.util.List;
import org.apache.commons.math3.stat.ranking.NaturalRanking;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.math.DoubleMath;
import com.google.common.primitives.Doubles;
/**
* 分数排名
* @author kakaka
*
*/
public class ScoreOrdering {
public static void main(String[] args) {
double[] score = { 45, 78, 99, 86, 77, 75, 95, 56, 86, 63, 71, 77 };
NaturalRanking ranking = new NaturalRanking();
double[] result = ranking.rank(score);
System.out.println("排名前分数: " + Doubles.asList(score));
System.out.println("排名后名次: " + Doubles.asList(result));
// 分数相同的排名处理,可以做名次舍入处理,java.math.RoundingMode
List ranks = Doubles.asList(result);
// RoundingMode.UP 排名归大,归后(归下)
List rankUp = Lists.transform(ranks, new Function() {
public Integer apply(Double input) {
return DoubleMath.roundToInt(input, RoundingMode.UP);
}
});
System.out.println("排名后名次处理(归后): " + rankUp);
// RoundingMode.DOWN 排名归小,归前(归上)
List rankDown = Lists.transform(ranks, new Function() {
public Integer apply(Double input) {
return DoubleMath.roundToInt(input, RoundingMode.DOWN);
}
});
System.out.println("排名后名次处理(归前): " + rankDown);
}
}
结果见:
排名前分数: [45.0, 78.0, 99.0, 86.0, 77.0, 75.0, 95.0, 56.0, 86.0, 63.0, 71.0, 77.0]
排名后名次: [1.0, 8.0, 12.0, 9.5, 6.5, 5.0, 11.0, 2.0, 9.5, 3.0, 4.0, 6.5]
排名后名次处理(归后): [1, 8, 12, 10, 7, 5, 11, 2, 10, 3, 4, 7]
排名后名次处理(归前): [1, 8, 12, 9, 6, 5, 11, 2, 9, 3, 4, 6]
考虑到分数由大到小排名,将数组统一处理成负数,并且有更简洁的办法,留意NaturalRanking的TiesStrategy策略:
double[] score = { 45, 78, 99, 86, 77, 75, 95, 56, 86, 63, 71, 77 };
List score1 = Lists.transform(Doubles.asList(score), new Function() {
public Double apply(Double input) {
return 0-input; // 统一处理成负数
}
});
//double[] score1 = {-45, -78, -99, -86, -77, -75, -95, -56, -86, -63, -71, -77 };
NaturalRanking ranking1 = new NaturalRanking();
double[] result1 = ranking1.rank(Doubles.toArray(score1));
System.out.println("排名前分数: " + score1);
System.out.println("排名后名次: " + Doubles.asList(result1));
//分数相同策略,打结策略
ranking1 = new NaturalRanking(TiesStrategy.MAXIMUM);
result1 = ranking1.rank(Doubles.toArray(score1));
System.out.println("分数相同排名后归后: " + Doubles.asList(result1));
ranking1 = new NaturalRanking(TiesStrategy.MINIMUM);
result1 = ranking1.rank(Doubles.toArray(score1));
System.out.println("分数相同排名后归前: " + Doubles.asList(result1));
结果为:
排名前分数: [-45.0, -78.0, -99.0, -86.0, -77.0, -75.0, -95.0, -56.0, -86.0, -63.0, -71.0, -77.0]
排名后名次: [12.0, 5.0, 1.0, 3.5, 6.5, 8.0, 2.0, 11.0, 3.5, 10.0, 9.0, 6.5]
分数相同排名后归后: [12.0, 5.0, 1.0, 4.0, 7.0, 8.0, 2.0, 11.0, 4.0, 10.0, 9.0, 7.0]
分数相同排名后归前: [12.0, 5.0, 1.0, 3.0, 6.0, 8.0, 2.0, 11.0, 3.0, 10.0, 9.0, 6.0]
分数排序处理,主要利用com.google.common.collect.Ordering, 处理比较简洁
double[] score = { 45, 78, 99, 86, 77, 75, 95, 56, 86, 63, 71, 77 };
// 自然排序,数字按大小,日期按先后排序
Ordering ordering = Ordering.natural();
List scoreOrdering = ordering.sortedCopy(Doubles.asList(score));
System.out.println("分数排序(由小到大): " + scoreOrdering);
Ordering reOrdering = Ordering.natural().reverse();
List scoreOrdering1 = reOrdering.sortedCopy(Doubles.asList(score));
System.out.println("分数排序(由大到小): " + scoreOrdering1);
结果
分数排序(由小到大): [45.0, 56.0, 63.0, 71.0, 75.0, 77.0, 77.0, 78.0, 86.0, 86.0, 95.0, 99.0]
分数排序(由大到小): [99.0, 95.0, 86.0, 86.0, 78.0, 77.0, 77.0, 75.0, 71.0, 63.0, 56.0, 45.0]