如何根据给定值返回评级

时间:2019-01-14 12:47:45

标签: c# performance coding-efficiency

我需要一种基于给定参数返回评级值的方法。评分类将评分的上限和下限存储为整数(从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;
    }

4 个答案:

答案 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;
}