c# - 为列表中的每个项目设置权重
问题描述
我有一个以逗号分隔的水果列表,它们按从最相关到最不相关的顺序列出。
例如:
"fruits":"apple, orange, lemon, apple, strawberry, pineapple, banana"
我需要根据列出的顺序和每个项目的重复次数为列表中的每个元素分配权重。
权重总和必须 = 100 (%)
但我无法想出一个数学函数来实现解决方案:
什么是实现这种行为的好通用算法?
也许 C# 中已经有一些选项可用?
解决方案
它有助于逐步思考。
让我们把它分成一个可行的列表......
var fruitList = "apple, orange, lemon, apple, strawberry, pineapple, banana"
.Split(", ".ToCharArray())
...它带有一个代表订单的索引,因为这很重要。
.Select((name, index) => {
return new {name, index + 1};
})
我们必须停下来想想订单与次数的相关性。他们必须在彼此之间分享分配的 100,但如何?订单真的很重要,而次数不那么重要(99/1),反之亦然(1/99),还是50/50?
让我们假设他们将相关性分成 50/50。您可以降低此数字以提供与次数更多的相关性,或增加它以使订单更具相关性。
var orderRelevance = .5;
var timesRelevance = 1 - orderRelevance;
假设它们都是唯一的,则时间相关性将是为时间相关性分配的权重除以水果的总数。
var timesWeightForOne = 100 * timesRelevance / fruitList.Count;
然后我们将分配剩余的 50%。我们假设它应该是线性分布的。
var orderWeightForOne = 100 * orderRelevance / fruitList.Sum(fruit => fruit.Index);
现在在计算权重时对它们进行分组。
var weighted = fruitList
.GroupBy(
fruit => fruit.name,
(name, fruits) => new {
name,
weight = fruits.Count() * timesWeightForOne +
fruits.Sum(fruit => fruit.index) * orderWeightForOne;
}
)
让我们按重量降序排列它们。
.OrderByDescending(fruit => fruit.weight)
并使它们可读。
.Select(fruit => {
var percent = Math.Round(fruit.weight, 2);
return $"{fruit.name}: {percent}%";
})
Console.WriteLine(string.Join("\r\n", weighted));
我不在编译器附近,所以可能会有错误,但这应该是要点。
推荐阅读
- c# - Xamarin Forms Picker 控件在 Entry 控件中输入时打开
- vim - 在 vim 命令中插入当前文件名不起作用
- android - Flutter - 多选 ListView
- python - 如何减少火花流中的两个键?
- wordpress - 我有一个 ); 显示在所有 wordpress 页面的顶部,也将显示在一些管理页面上
- django - Docker 包含接收未经请求的 HTTP POST 请求
- cookies - AspNetBoilerplate - 服务器端 JavaScript 代码注入
- python - 使用 Selenium python 在 chrome 中下载 pdf
- php - 根据键获取数组的索引
- javascript - 在数据库中散列密码有什么意义?