我做了一个彩票计划:http://yadi.sk/d/bBKefn9g4OC7s
以下是完整的源代码:http://yadi.sk/d/rnQMfrry4O8cu
Random rnd = new Random();
int[] loto;
loto = new int[7];
for (int f = 1; f <= 6; f++) {
loto[f] = rnd.Next(1, 50); // Generating random number between 1-49
for (int h = 1; h < f; h++) {
if (loto[f] == loto[h]) { // Check with other numbers for the case of duplicate
loto[f] = rnd.Next(1, 50); // If there is a duplicate create that number again
}
}
}
本节我在1-49
之间生成随机的6个不同的数字我也想知道在这个例子中,嵌套循环会增加自发性吗?
我最多3-4次,这个程序错了,还是我太不走运了?
(请注意:那是我的第一个节目)
对于所有想要帮助我的人:我真的是编程的初学者(c#昨天| c ++ 3周我猜),如果你们澄清你在代码中的含义,它会很棒。 请不要给我极端的硬编码示例(我不想退出c#)
答案 0 :(得分:3)
我认为除了for循环声明之外它是正确的:记住C#中的数组是从零开始的。因此循环应如下所示:
for (int f = 0; f < 7; f++)
甚至更好:
for (int f = 0; f < loto.Length; f++)
更新:我无法评论其他答案(声誉太少),因此我必须在此发布:
@Dan:只有一个循环不正确,因为在Loto中不允许两次具有相同的数字。在他的内部循环中,1342检查创建的随机数是否已经存在,因此将其遗漏是不正确的。
@James:由于1342刚刚开始编程,我认为没有必要使用静态字段。我猜他或她的全部代码都在Main
方法中,因此使用静态变量没有任何好处。
答案 1 :(得分:3)
您的方法看起来不安全,因为在内循环中再次从Random
获取值并不能保证它将返回非重复值。对于1-49的低值,您可以使用像这样的简单随机选择算法
var numbers = new List<int>();
for (int i = 1; i <= 49; i++) {
numbers.Add(i);
}
Random r = new Random();
var loto = new int[6];
for (int f = 0; f < 6; f++) {
int idx = r.Next(0, numbers.Count);
loto[f] = numbers[idx];
numbers.RemoveAt(idx);
}
请注意,这在性能方面远非最佳解决方案,但如果您只在几秒钟或更长时间内运行一次,那么应该没问题。
答案 2 :(得分:1)
这里有一些问题 - 你有一个太多的循环开始,没有评论。
请参阅下面的(过度评论)示例:
// This is static so we don't recreate it every time.
private static Random _rnd;
static void Main(string[] args)
{
_rnd = new Random();
// You can declare and initialise a variable in one statement.
// In this case you want the array size to be 6, not 7!
Int32[] lotoNumbers = new Int32[6];
// Generate 10 sets of 6 random numbers
for (int i = 0; i < 10; i++)
{
// Use a meaningful name for your iteration variable
// In this case I used 'idx' as in 'index'
// Arrays in c# are 0-based, so your lotto array has
// 6 elements - [0] to [5]
for (Int32 idx = 0; idx < 6; idx++)
{
// Keep looping until we have a unique number
int proposedNumber;
do
{
proposedNumber = _rnd.Next(1, 50);
} while (lotoNumbers.Contains(proposedNumber));
// Assign the unique proposed number to your array
lotoNumbers[idx] = proposedNumber;
}
}
}
你应该得到一个6元素的长数组,其中包含1到50之间的6个随机数。 希望有所帮助!
编辑: 同样值得注意詹姆斯的答案 - 如果你在循环中做上述事情,由于种子的使用方式,每次从Random获得相同的值。使用静态版本的Random会得到更好的结果。
答案 3 :(得分:1)
您不希望每次都重新创建Random
的新实例,这可能是您每次都获得类似值的原因。更好的方法是创建一个static
Random
实例并在整个应用中使用它 - 这可以为您提供更实际的结果,例如。
using System.Collections.Generic;
using System.Linq;
...
static readonly Random rand = new Random();
...
List<int> lottoNumbers = new List<int>(6);
int drawnNumber = -1;
for (int i = 0; i < lottoNumbers.Count; i++) {
do
{
drawnNumber = rand.Next(1, 50); // generate random number
}
while (lottoNumbers.Contains(drawnNumber)) // keep generating random numbers until we get one which hasn't already been drawn
lottoNumbers[i] = drawnNumber; // set the lotto number
}
// print results
foreach (var n in lottoNumbers)
Console.WriteLine(n);
答案 4 :(得分:1)
为了便于测试,我已经为您保留了控制台日志和static void main。
您不需要两次迭代。另外 - 数组是基于0的,所以要么f必须等于0,要么小于7.我在下面等于0。
我创建了一个递归方法,它创建一个新值并检查数组contains是否为该值。如果它不包含它,它会添加它。但如果确实包含它,则该方法会调用自己来查找新值。它将继续执行此操作,直到找到新值。
Recursive methods是自称的方法。
,请不要尝试使用大于50的索引填充数组,因为您将获得无限循环。private static readonly Random Rnd = new Random();
static void Main(string[] args)
{
var loto = new int[7];
for (int f = 0; f <= 6; f++)
{
var randomValue = GetRandomNumberNotInArr(loto);
Console.WriteLine(randomValue);
loto[f] = randomValue;
}
Console.Read();
}
/// <summary>
/// Finds a new random value to insert into arr. If arr already contains this another
///random value will be found.
/// </summary>
/// <param name="arr">arr with already found values</param>
/// <returns></returns>
private static int GetRandomNumberNotInArr(int[] arr)
{
var next = Rnd.Next(1, 50);
return !arr.Contains(next) ? next : GetRandomNumberNotInArr(arr);
}
答案 5 :(得分:0)
我可以看到你正在尝试模拟1到50之间的6个抽奖号码。
你的代码有一些逻辑错误,但不是修复它我建议以不同的方式做它。
有几种方法可以解决这个问题;一个常见的是:
Create an empty collection of numbers.
while there aren't enough numbers in the collection
let randomNumber = new random number in the appropriate range
if (randomNumber isn't already in the collection)
add randomNumber to the collection
但是还有另一种可以很好地扩展的方法,所以我将演示这个(其他人可能已经写过另一种方法):
Add to a collection all the numbers you want to choose from
Randomly rearrange (shuffle) the numbers in the collection
Draw the required number of items from the collection
这几乎就是现实生活中的彩票。
要收集一个集合,我们可以使用Fisher-Yates Shuffle。这是一个实现:
/// <summary>Used to shuffle collections.</summary>
public class Shuffler
{
/// <summary>Shuffles the specified array.</summary>
/// <typeparam name="T">The type of the array elements.</typeparam>
/// <param name="array">The array to shuffle.</param>
public void Shuffle<T>(IList<T> array)
{
for (int n = array.Count; n > 1;)
{
int k = _rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
private readonly Random _rng = new Random();
}
这是一个完整的可编辑示例。我在这个例子中避免使用Linq,因为我不想让你感到困惑!
using System;
using System.Collections.Generic;
namespace Demo
{
public static class Program
{
private static void Main()
{
int[] lotoDraw = createDraw();
Shuffler shuffler = new Shuffler();
shuffler.Shuffle(lotoDraw); // Now they are randomly ordered.
// We want 6 numbers, so we just draw the first 6:
int[] loto = draw(lotoDraw, 6);
// Print them out;
foreach (int ball in loto)
Console.WriteLine(ball);
}
private static int[] draw(int[] bag, int n) // Draws the first n items
{ // from the bag
int[] result = new int[n];
for (int i = 0; i < n; ++i)
result[i] = bag[i];
return result;
}
private static int[] createDraw() // Creates a collection of numbers
{ // from 1..50 to draw from.
int[] result = new int[50];
for (int i = 0; i < 50; ++i)
result[i] = i + 1;
return result;
}
}
public class Shuffler
{
public void Shuffle<T>(IList<T> list)
{
for (int n = list.Count; n > 1; )
{
int k = _rng.Next(n);
--n;
T temp = list[n];
list[n] = list[k];
list[k] = temp;
}
}
private readonly Random _rng = new Random();
}
}