我需要一种基于给定参数返回评级值的方法。评分类将评分的上限和下限存储为整数(从xml文件读取)。
直到现在,我有一种与下面的代码类似的方法,但是我正在寻找一种“更智能”且更有效的方法来获得评分。
private int GetRating(Ratings ratings, double rawValue)
{
int finalRating = 0;
if (rawValue <= ratings.Rating_1_upperLimit)
finalRating = 1;
if (rawValue >= ratings.Rating_2_lowerLimit && rawValue <= ratings.Rating_2_upperLimit)
finalRating = 2;
if (rawValue >= ratings.Rating_3_lowerLimit && rawValue <= ratings.Rating_3_upperLimit)
finalRating = 3;
if (rawValue >= ratings.Rating_4_lowerLimit && rawValue <= ratings.Rating_4_upperLimit)
finalRating = 4;
if (rawValue >= ratings.Rating_2_lowerLimit)
finalRating = 5;
return finalRating;
}
答案 0 :(得分:0)
这可能在边界连续的情况下起作用:
if input.gsub!(/(\d{3})年(\d{2})月(\d{2})日/) { "#{$2}/#{$3}/#{$1.to_i + 1911}" }
puts 'dates have been converted'
else
puts 'no dates could be found'
end
答案 1 :(得分:0)
我想“有效”是指重复代码更少?因为就速度而言,无法显着加快代码速度。我还假设一个等级的下限等于上一个等级的上限。
您的Ratings
类仅需要存储4个双打的列表,这是每个等级的界限。假设这些数字分别是20、40、60、80。
public List<double> Boundaries = new List<double>() { 20, 40, 60, 80 };
小于20的所有事物的评分均为1,小于40的所有事物的评分为2,小于60的所有事物的评分为3,小于80的所有事物的评分为4,其他所有事物的评分为5。
您可以过滤出少于rawValue
的数字并计算剩余数量。而加1就是评分:
return ratings.Boundaries.Where(x => rawValue >= x).Count() + 1;
答案 2 :(得分:0)
在您的代码中,性能并不是什么大问题。因此,改善它的唯一方法就是缩短它。但是,没有什么可缩短的,但是您可以这样做,以便在将来获得更多评分时可以更好地扩展:
public struct Rating
{
public int Lower { get; set; }
public int Upper { get; set; }
public int FinalRating { get; set; }
}
private int GetRating(IEnumerable<Rating> ratings, double rawValue)
{
int finalRating
foreach(var rating in ratings)
{
int currentRating;
if(rawValue >= rating.Lower && rawValue <= rating.Upper)
currentRating = rating.FinalRating;
Math.Max(currentRating, finalRating);
}
return finalRating;
}
此编解码器将等级分配给一系列值,然后根据这些值进行测试。通过将评分作为IEnumerable传递,我们可以对它们进行评估(并选择最高评分),而不必为每个新评分引入新的if。您只需将新的评级实例添加到IEnumerable评级中并就餐。 但是,这将比普通if-else慢,尽管在更大的程序中,更大的可维护性超过了速度优势。
答案 3 :(得分:0)
如果范围很密集,即
ratings.Rating_N_upperLimit == ratings.Rating_N+1_lowerLimit
例如
[1_lower_limit..1_upper_limit)[2_lower_limit..2_upper_limit)...[N-1_lower_limit..N-1_upper_limit)[N_lower_limit..N_upper_limit)
你想要
0 if rawValue < 1_lower_limit
k if rawValue <= k_lower_limit && rawValue < k_upper_limit
N + 1 if rawValue >= N_upper_limit
然后您可以使用二进制搜索:
// Lower limit, must be sorted
static double[] s_Limits = new double[] {
10.0,
20.0,
30.0,
40.0,
50.0,
100.0,
};
...
private static int GetRating(double rawValue) {
if (rawValue >= s_Limits[s_Limits.Length - 1])
return s_Limits.Length;
int index = Array.BinarySearch(s_Limits, rawValue);
return index < 0 ? -index - 1: index + 1;
}