随机数组列表

时间:2014-03-18 15:05:51

标签: c# random arraylist

我正在尝试使用随机数组列表,这是代码

private static string getSearchEngine()
{
    ArrayList url = new ArrayList();
    url.Add("www.google.com");
    url.Add("www.bing.com");
    url.Add("www.yahoo.com"); 
    Random rnd = new Random();
    int i = rnd.Next(0, url.Count);
    return url[i].ToString();
}

private static void DoMore_Functionality_Using_engName()
{
    for(int i = 0; i < 300; i++)
        string engName = getSearchEngine();
}

我希望每个搜索引擎只能使用100次。如果我使用上面的代码,随机发生器可以选择其中任何一个超过100次。如何修改代码才能执行此操作?

由于 Rashmi

3 个答案:

答案 0 :(得分:3)

我认为你可以通过在你的方法之外定义你的收藏来做到这一点。将每个搜索引擎添加到你的列表100次,然后每次你选择一个随机引擎,从你的收藏中删除该项目。这样的事情:< / p>

static List<string> engines = new List<string> (Enumerable.Repeat("www.google.com", 100)
        .Concat(Enumerable.Repeat("www.bing.com", 100))
        .Concat(Enumerable.Repeat("www.yahoo.com", 100)));

static Random rnd = new Random();
private static string getSearchEngine()
{
    int i = rnd.Next(0, engines.Count);
    var temp = engines[i];
    engines.RemoveAt(i);
    return temp;
}

答案 1 :(得分:1)

这是一种通过随机播放来实现这一目标的方法:

List<string> urls = new List<string> { "www.google.com", "www.bing.com", "www.yahoo.com" };
List<int> randomIdx = new List<int> (Enumerable.Repeat(0, 100)
                                     .Concat(Enumerable.Repeat(1, 100))
                                     .Concat(Enumerable.Repeat(2, 100)));

Random r = new Random();
// This is the Fisher-Yates Shuffle
// see: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
for (int i = randomIdx.Count - 1; i > 0; i--) 
{
    int j = r.Next(0,i);
    int tmp = randomIdx[i];
    randomIdx[i] = randomIdx[j];
    randomIdx[j] = tmp;
}

// Iterate through our random list and write each one out
for (int i = 0; i < randomIdx.Count; i++)
{
    Console.WriteLine(urls[randomIdx[i]]);
}

因此,要将此工作添加到DoMore_Functionality_Using_engName()函数中,您将在类中初始化设置列表并对其进行随机化,然后设置一个索引属性,以跟踪列表中的位置。然后在DoMore_Functionality_Using_engName()中,您将获得下一个结果,然后递增索引。

答案 2 :(得分:0)

您需要将每个搜索引擎与计算器的使用次数相关联。为此,您需要将集合保留在内存中,而不是每次都创建它。

首先,创建一个表示数据的类:

class SearchEngine
{
    public SearchEngine(string url, int counter)
    {
        Url = url;
        Counter = counter;
    }

    public string Url { get; set; }
    public int Counter { get; set; }
}

其次,在某处创建一个引擎集合作为私有字段:

private Random _random = new Random();
private IEnumerable<SearchEngine> _engines = new[]
{
    new SearchEngine("www.google.com", 0),
    new SearchEngine("www.bing.com", 0),
    new SearchEngine("www.yahoo.com", 0)
};

获取随机搜索引擎的方法应该是这样的:

private string GetRandomSearchEngine()
{
    var searchEngine = _engines
    // randomize the collection
        .OrderBy(x => _random.Next())
    // skip items with invalid counter
        .SkipWhile(t => t.Counter >= 100)
        .First();
    // update the counter
    searchEngine.Counter++;
    return searchEngine.Url;
}

修改

正如 @Matt Burland 建议使用_random.Next()是一种更好的方法来随机化集合。 他还提出了另一个有效点:当所有计数器达到100 时会发生什么?

在这种情况下,上面的代码将抛出异常(即First()方法)。假设您不想要,可以使用FirstOrDefault()并检查null。如果返回的项目为null,则所有计数器都已达到100。

private bool TryGetRandomSearchEngine(out string url)
{
    var searchEngine = _engines
    // randomize the collection
        .OrderBy(x => _random.Next())
    // skip items with invalid counter
        .SkipWhile(t => t.Counter >= 100)
        .FirstOrDefault();
    if(searchEngine != null)
    {        
        // update the counter
        searchEngine.Counter++;
        url = searchEngine.Url;
        return true;
    }
    url = String.Empty;
    return false;
} 

在代码中的某处,您可以使用上面的方法:

string searchEngineUrl;
while(TryGetRandomSearchEngine(out searchEngineUrl))
{
    PerformSearch(searchEngineUrl, searchTerms);
}