2016-05-14 103 views
0

我得到了一個對象的數組列表。每個對象都有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

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

回答

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