随机方法返回两个没有重复的值

时间:2018-08-01 18:46:32

标签: c#

我创建了两种从数据库表中获取随机值的方法

此方法将返回整数随机值

private int GetDayValue()
{
    Random rnd = new Random();
    List<int> days = GetDays();
    int r = rnd.Next(days.Count);
    return days[r];
}

此方法还将返回整数随机值

private int GetPeriodValue(string grd_id)
{ 
    Random rnd = new Random();
    List<int> periods = GetPeriods(grd_id);
    int r = rnd.Next(periods.Count);
    return periods[r];
}

这里有一个for循环将从两种方法中获取随机值

for (int z = 0; z <= secPortion; z++)
{
    //here the random value of day
    day = GetDayValue();

    //here the random value of period
    period = GetPeriodValue(grd_id);   

    //this method will insert the value on database table                  
    SetFirstShot(teacher, sub, sec, period, day);                             
}

我的问题:

我要创建的方法将同时返回天和周期的随机值,例如随机值(例如:3,5 ... 4,6 .... 1,1),并且在循环期间不重复,例如,4,6将生成一次,然后再生成另一个随机数值,但如果为4,6,该方法将再次创建一个随机值。

4 个答案:

答案 0 :(得分:0)

您可以改用具有良好随机分布方面的哈希函数。每次都对相同的输入返回相同值的哈希函数,而结果将“似乎”是随机的,这可能就是您所需要的所有“随机性”。

using System;
using System.IO;
using System.Security.Cryptography;

// ...

using (var stream = new MemoryStream())
using (var writer = new BinaryWriter(stream))
using (var hash = MD5.Create())
{
    writer.Write(day);
    writer.Write(period);
    var data = md5Hash.ComputeHash(stream.ToArray());
    var randomNumber = BitConverter.ToInt32(data);
}

额外的好处是您不必将以前计算的值存储在任何类型的数据库中。具有相同哈希算法的任何两个代理将生成相同的哈希。这些值可能不是完全唯一的,但是它们在输入之间应有很大的不同,同时还应是确定性且没有隐藏状态。真正独特的要求您查询外部状态,并且如果您的系统是分布式的,可能会引入竞争条件。

答案 1 :(得分:0)

看来GetDays()GetPersiodValue()返回了两个int列表,所以我正在为它们编写两个模拟方法。

static List<int> GetDays()
{
    return new List<int>() { 1, 2, 3, 4, 5, 6, 7 };
}

static List<int> GetPeriods()
{
    return new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
}

您需要做的第一件事是将new Random()从方法中移出(以使其位于循环之外)。否则,当您如此快速地进行迭代时,它将不断为您提供相同的编号。

static int GetRandomDay(Random rnd)
{
    var days = GetDays();
    return days[rnd.Next(days.Count)];
}

static int GetRandomPeriod(Random rnd)
{
    var periods = GetPeriods();
    return periods[rnd.Next(periods.Count)];
}

然后,我将执行类似的操作,以查看生成的随机值对是否之前已生成。如果没有,则添加到列表(或您的数据库)。

static void Main(string[] args)
{
    var RandomList = new List<Tuple<int, int>>();

    Random rnd = new Random();

    for (int i =0; i < 10; i++)
    {
        bool isUnique = false;
        do
        {
            int day = GetRandomDay(rnd);
            int period = GetRandomPeriod(rnd);
            if(RandomList.Where(x => x.Item1 == day && x.Item2 == period).FirstOrDefault() == null)
            {
                RandomList.Add(new Tuple<int, int>(day, period));
                isUnique = true;
            }

        } while (!isUnique);
    }

    Console.ReadLine();
}

答案 2 :(得分:0)

我尝试使用KeyValuePair并解决了,它运作良好! 这是我使用的代码:

    // I created a list contain two pairs..
        List<KeyValuePair<int, int>> dictionary = new List<KeyValuePair<int, int>>();
        for (int z = 0; z < secPortion; z++)
        {
        day = GetDayValue();
        period = GetPeriodValue(grd_id);

    //here I pass the value of day and period to the pairs
        KeyValuePair<int, int> myItem = new KeyValuePair<int, int>(day, period);
//here I created a list which is the list of values for the random key, if it is exist or not.
        List<int> values = (from kvp in dictionary where kvp.Key == day select kvp.Value).ToList();

    // this is a bool variable its value by default is true, once there is a duplicated value it will be changed to false....

    bool FirstChecker = true;
        if (values.Contains(period))
        {
        FirstChecker = false;
        z--;
        }
        else
        {
        dictionary.Add(myItem);
        SetFirstShot(teacher, sub, sec, period, day);
        }
        }

答案 3 :(得分:0)

我认为this是您所需要的。

  

尽管该示例是一维数组的解决方案,但实际上在您的情况下,两个列表daysperiods可以映射到一个长度为days.Count * periods.Count的序列。或者,您可以分别为每个列表执行此操作,但是某些情况会丢失。