从数组列表中选择基于其百分比的值

问题描述:

我得到了一个对象的数组列表。每个对象都有2个值,分别为contentweightcontent只是一个简单的字符串,而weight决定应该使用字符串的频率的百分比。从数组列表中选择基于其百分比的值

如果我有数组中2个对象:

对象1: 内容:您好 重量:20

对象2: 内容:哎 重量:80

第一对象content应该使用20%的次数,而第二个对象content应该使用80%的次数。

如何根据weight决定选择哪个content

我得到了下面的代码至今:

foreach (ContentModels cont in match_array) 
{ 
    if (match_array.Count == 1) 
    { 
     match = cont.content; 
     break; 
    } 
} 

这几乎选择第一content如果ArrayList中只包含一个对象,但我不知道是否有一个以上的对象是什么做的?

+2

是Java代码错误? – KevinO

+0

你想得到的对象有最大或最小百分比? –

好吧,我想在没有看别人的代码的情况下对此进行刺探。这是我想出来的。

顺便说一句,我希望它是错误的Java标记,而不是C#标记:D。

这是整个程序。什么下面如下是每片

.NET Fiddle

我选择带的每个元素是在一个比的部分的说明。因此,在您的示例中,您的总数为100(20 + 80),这意味着应该在20%的时间内选择20内容模型。如果你想约束你的内容模型,使得它们的总权重总和为100,那么应该在你创建它们的时候完成。

所以这是我的解决方案。
一是内容模型:

class ContentModel 
{ 
    public string Content { get; set; } 
    public int Weight { get; set; } 
} 

然后测试案例的列表:

static List<ContentModel> contentOptions = new List<ContentModel> 
{ 
    new ContentModel 
    { 
     Content = "hello", 
     Weight = 20 
    }, 
    new ContentModel 
    { 
     Content = "hey", 
     Weight = 80 
    }, 
    new ContentModel 
    { 
     Content = "yo dawg", 
     Weight = 90 
    } 
}; 

鉴于这些测试情况下,我们希望看到“你好”出现的约10.5%时间(20 /(80 + 90 + 20))* 100。其余测试用例如此。

这里的发电机,使这种情况发生:

这里所有我们要做的是搞清楚总重量是什么,我们正在与合作。然后,我们将选择一个随机数字,然后遍历每个模型,询问“这个内容模型中是否有这个数字?“如果不是,那么减去内容模型的重量并移动到下一个模型,直到我们得到一个模型,其中的选择 - 重量为< 0.在这种情况下,我们选择了该模型,我希望这是合理的。 (注意:如果您更改选项的源列表,我会选择每次重新计算总重量。如果您只是将列表设置为只读,那么您可以将该.Sum()调用移到while循环之外。)

static IEnumerable<string> GetGreetings() 
{ 
    Random generator = new Random(); 

    while (true) 
    { 
     int totalWeight = contentOptions.Sum(x => x.Weight); 
     int selection = generator.Next(0, totalWeight); 
     foreach (ContentModel model in contentOptions) 
     { 
      if (selection - model.Weight > 0) 
       selection -= model.Weight; 
      else 
      { 
       yield return model.Content; 
       break; 
      } 
     } 
    } 
} 

最后,这里也将考验这整个事情的主要方法:

static void Main(string[] args) 
{ 
    List<string> selectedGreetings = new List<string>(); 

    /* This will get 1000 greetings, 
    * which are the Content property of the models, group them by the greeting, 
    * count them, and then print the count along with the greeting to the Console. 
    */ 
    GetGreetings() 
     .Take(1000) 
     .GroupBy(x => x) 
     .Select(x => new { Count = x.Count(), Content = x.Key }) 
     .ToList() 
     .ForEach(x => Console.WriteLine("{0} : {1}", x.Content, x.Count)); 

    Console.ReadLine(); 
} 

下面是一个运行我的结果通过:

Results

+0

这么详细的帖子,非常感谢! – Muki