这是一个函数,它创建一个数组并将其从LoLim
填充到HiLim
,然后将该顺序洗牌:
static Random random = new Random(); //these two statics are to make a random number, i need the first static to be outside the function so it won't keep making the same random number
static int RandomNum(int LoLim, int HiLim, int index)
{
var nums = Enumerable.Range(LoLim,HiLim).ToArray(); //these next lines make an array from LoLim to HiLim and then shuffle it
for (int i = 0; i < nums.Length; i++)
{
int randomIndex = random.Next(nums.Length);
int temp = nums[randomIndex];
nums[randomIndex] = nums[i];
nums[i] = temp;
}
return nums[index];
然后我有这个函数创建一个二维数组然后打印它。它使用RandomNum
但不是我想要的方式,但我不知道如何使它工作。
static Array Matrix(int Rows, int Columns) //this is a function to initiate and print the array
{
int[,] LotteryArray = new int[Rows, Columns];
for (int i = 0; i < LotteryArray.GetLength(0); i++) //this is a series of loops to initiate and print the array
{
for (int j = 0; j < LotteryArray.GetLength(1); j++)
{
LotteryArray[i, j] = RandomNum(1,46,j); //the numbers are supposed to be between 1 and 45, so i tell it to do it until 46 because the upper limit is exclusive
Console.Write("{0,3},", LotteryArray[i, j]); //the {0,3} the 3 is three spaces after the first variable
}
Console.WriteLine();
}
return LotteryArray;
基本上我希望它每个“行”调用RandomNum
,这样它可以随机播放数组,然后我希望它拉出nums[index]
并将其打印出来。我想要这个的原因是我每行都可以有非重复的随机数。例如:我不希望行是“21,4,21,5,40,30”。
答案 0 :(得分:1)
您的代码存在各种问题,即使它有效。 “逻辑”问题是:
Random
数字生成器,而是使用RNGCryptoServiceProvider
(参见http://www.cigital.com/papers/download/developer_gambling.php,但请注意这一点是一个比另一个问题小得多的问题...如果生成的随机播放都是等概率的话,我们可以通过“稍微不那么随机”的改组来生存。Enumerable.Range()
您的编码问题不同:您必须在某处保存洗牌行,然后获取第一个列值。
这里我使用一个类用shuffling封装一行
public class ShuffledRow
{
public static readonly Random Random = new Random();
public readonly int[] Row;
/// <summary>
/// Generates and shuffles some numbers
/// from min to max-1
/// </summary>
/// <param name="min"></param>
/// <param name="max">Max is excluded</param>
public ShuffledRow(int min, int max)
{
int count = max - min;
Row = Enumerable.Range(min, count).ToArray();
Shuffle(Row);
}
private static void Shuffle<T>(T[] array)
{
// Fisher-Yates correct shuffling
for (int i = array.Length - 1; i > 0; i--)
{
int j = Random.Next(i + 1);
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
另一个问题:除非你知道自己在做什么,否则不要在C#中使用多维数组。可悲的是,他们是.NET的混蛋和被遗忘的孩子。使用锯齿状数组(数组数组)。
public static int[][] Matrix(int rows, int columns)
{
int[][] lottery = new int[rows][];
for (int i = 0; i < lottery.Length; i++)
{
ShuffledRow sr = new ShuffledRow(1, 46);
lottery[i] = sr.Row;
Array.Resize(ref lottery[i], columns);
Console.WriteLine(
string.Join(",", lottery[i].Select(
x => string.Format("{0,3}", x))));
}
return lottery;
}
public static int[][] Matrix(int rows, int columns)
{
int[][] lottery = new int[rows][];
for (int i = 0; i < lottery.Length; i++)
{
ShuffledRow sr = new ShuffledRow(1, 46);
lottery[i] = new int[columns];
for (int j = 0; j < columns; j++)
{
lottery[i][j] = sr.Row[j];
Console.Write("{0,3},", lottery[i][j]);
}
Console.WriteLine();
}
return lottery;
}
我准备了两个版本的 Matrix 函数,一个与你正在使用的版本更相似,一个更LINQ和“高级”。
答案 1 :(得分:0)
生成随机数确实不使用随机函数,请使用:
private static RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
// Main method.
public static int[] generateTrueRandomOK()
{
const int totalRolls = 2500;
int[] results = new int[50]; //Number of random ints that you need
// Roll the dice 25000 times and display
// the results to the console.
for (int x = 0; x < totalRolls; x++)
{
byte roll = RollDice((byte)results.Length);
results[roll - 1]++;
}
return results;
}
// This method simulates a roll of the dice. The input parameter is the
// number of sides of the dice.
public static byte RollDice(byte numberSides)
{
if (numberSides <= 0)
throw new ArgumentOutOfRangeException("numberSides");
// Create a byte array to hold the random value.
byte[] randomNumber = new byte[1];
do
{
// Fill the array with a random value.
rngCsp.GetBytes(randomNumber);
}
while (!IsFairRoll(randomNumber[0], numberSides));
// Return the random number mod the number
// of sides. The possible values are zero-
// based, so we add one.
return (byte)((randomNumber[0] % numberSides) + 1);
}
private static bool IsFairRoll(byte roll, byte numSides)
{
// There are MaxValue / numSides full sets of numbers that can come up
// in a single byte. For instance, if we have a 6 sided die, there are
// 42 full sets of 1-6 that come up. The 43rd set is incomplete.
int fullSetsOfValues = Byte.MaxValue / numSides;
// If the roll is within this range of fair values, then we let it continue.
// In the 6 sided die case, a roll between 0 and 251 is allowed. (We use
// < rather than <= since the = portion allows through an extra 0 value).
// 252 through 255 would provide an extra 0, 1, 2, 3 so they are not fair
// to use.
return roll < numSides * fullSetsOfValues;
}
答案 2 :(得分:0)
您可以使用锯齿状数组:
Random random = new Random();
int[] RandomNum(int LoLim, int HiLim)
{
var nums = Enumerable.Range(LoLim,HiLim).ToArray();
for (int i = 0; i < nums.Length; i++)
{
int randomIndex = random.Next(nums.Length);
int temp = nums[randomIndex];
nums[randomIndex] = nums[i];
nums[i] = temp;
}
return nums;
}
int[][] Matrix(int Rows, int Columns)
{
int[][] LotteryArray = new int[Rows][];
for (int i = 0; i < LotteryArray.Length; i++)
{
LotteryArray[i] = RandomNum(1,46);
for (int j = 0; j < LotteryArray[i].Length; j++)
{
Console.Write("{0,3},", LotteryArray[i][j]);
}
Console.WriteLine();
}
return LotteryArray;
}