我创建了两种从数据库表中获取随机值的方法
此方法将返回整数随机值
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
,该方法将再次创建一个随机值。
答案 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是您所需要的。
尽管该示例是一维数组的解决方案,但实际上在您的情况下,两个列表
days
和periods
可以映射到一个长度为days.Count * periods.Count
的序列。或者,您可以分别为每个列表执行此操作,但是某些情况会丢失。