根据arraylist的百分比从arraylist中选择值

时间:2016-05-14 14:42:01

标签: java c# arraylist

我有一个对象的arraylist。每个对象都有2个值,contentweightcontent只是一个简单的字符串,weight决定字符串的使用频率百分比。

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

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

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

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

我如何根据content确定选择哪个weight

到目前为止,我得到了以下代码:

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

如果arraylist只包含一个对象,那么它几乎会选择第一个content但我不知道如果有多个对象会怎么做?

1 个答案:

答案 0 :(得分: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
    }
};

鉴于这些测试用例,我们希望看到“Hello”出现约10.5%的时间(20 /(80 + 90 + 20))* 100.其他测试用例依此类推。

以下是发生这种情况的生成器:

我们要做的就是弄清楚我们正在使用的总重量是多少。然后我们将选择一个随机数并通过每个模型询问“这个内容模型中的数字是多少?”如果不是,则减去该内容模型的权重并移至下一个,直到我们到达选择的模型 - 权重为&lt;在这种情况下,我们选择了模型。我希望这是有道理的。

(注意:我选择每次重新计算总重量,以防您更改选项的源列表。如果您只读取该列表,那么您可以在while循环外移动.Sum()调用。)

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