请教一个循环判断问题

qqqq6119 2008-07-09 09:22:14
部分代码如下:
public string getRandomNum()
{
string[] arr = new string[4];
int[] arrNum = new int[4];
Random ra = new Random();
int tmp = 0;
for (int i = 0; i <= 3; i++)
{
tmp = ra.Next(0, 9); //随机取数
arrNum[i] = getNum(arrNum, tmp, ra,i); //取出值赋到数组中
arr[i] = Convert.ToString(arrNum[i]);
}

string qwer = arr[0] + arr[1] + arr[2] + arr[3];
return qwer;
}
public int getNum(int[] arrNum, int tmp, Random ra,int i)
{
int n = 0;
while (n <= i - 1)
{
if (arrNum[n] == tmp) //利用循环判断是否有重复
{
tmp = ra.Next(0, 9); //重新随机获取。
getNum(arrNum, tmp, ra,i);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
}
n++;
}
return tmp;
}

我这个程序主要目的就是随即选出4个不同的数字。经过测试,还是有部分数据出现重复数字。自己研究半天还是没明白到底哪里出现问题。请各位帮忙看看。V2005下编的。另外我用button测试结果,在按得比较快的时候,有些程序回弹出一些错误,请问这个是什么原因——非本程序。
...全文
147 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
falx2004 2008-07-09
  • 打赏
  • 举报
回复
Random ra = new Random();
移到循环里面应该能解决
windows内核的研究很有必要
random产生的随机数实际上是个伪随机
当执行速度很快的时候上一次的操作并未释放
建议在循环内重新构造 random
家鸣 2008-07-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 suyiming 的回复:]
如果是用到 Random 函数就有重复 这个是绝对,因为Random 本身也是个算法,不是随机的,如果当时间间隔非常短的时候,抽取重复的几率是100%
所以要彻底避免重复,只能用个方法去防止,这里我可以介绍递归算法。
[/Quote]
首先,Random是用某一种子初始化后,开始一系列'伪'随机数,如果构建的Random都具有相同的种子,就会生成相同的数字系列。
但如果仅是使用Next来生成随机数,不会出现重复的几率是100%。

仔细看了下楼主的代码,递归函数出了问题。改成如下:

public int getNum(int[] arrNum, int tmp, ref Random ra, int i)
{
int n = 0;
int result = tmp;
while (n <= i - 1)
{
if (arrNum[n] == tmp) //利用循环判断是否有重复
{
tmp = ra.Next(0, 9); //重新随机获取。
result=getNum(arrNum, tmp, ref ra, i);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
}
n++;
}
return result;
}

nattystyle 2008-07-09
  • 打赏
  • 举报
回复
时间种子。在某一段时间内只能获取一个数。
Magic_YJL 2008-07-09
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 qqqq6119 的回复:]
看到这些热心人回复我很高兴。
我的意思是:我的逻辑上好像没有什么错误。但是结果却出现偏差,是不是我有什么逻辑上的漏洞。

第一个函数用于生成一个随机数,然后给第二个函数判断。
这个新生成数字与前边所有的已知数字进行比较。如果相同,就重新生成一个数字重新与所有数字比较。
直到这个新生数字和前边都不重复,最后达到我期望的目标。

前边各位大大们说的Random非常容易生成重复数字,这个可是用第二个函数…
[/Quote]
逻辑上没有漏洞,但是实现上有漏洞
shadowgreen 2008-07-09
  • 打赏
  • 举报
回复
路过,学习···
友情UP
qqqq6119 2008-07-09
  • 打赏
  • 举报
回复
看到这些热心人回复我很高兴。
我的意思是:我的逻辑上好像没有什么错误。但是结果却出现偏差,是不是我有什么逻辑上的漏洞。

第一个函数用于生成一个随机数,然后给第二个函数判断。
这个新生成数字与前边所有的已知数字进行比较。如果相同,就重新生成一个数字重新与所有数字比较。
直到这个新生数字和前边都不重复,最后达到我期望的目标。

前边各位大大们说的Random非常容易生成重复数字,这个可是用第二个函数判断过了,应该不是重复了。

但是程序结果依然有问题,我在想是不是我考虑的不周全。

我是新手,C#接触不久,请各位多多关照。
Magic_YJL 2008-07-09
  • 打赏
  • 举报
回复
写了控制台的应用程序,供LZ参考一下:


using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace JustTry
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(GenerateRandomCode(i));
}
Console.ReadLine();
}

/// <summary>
/// 获取指定长度的不重复的随即数
/// </summary>
/// <param name="codeLength">随即数的长度</param>
/// <returns>返回生成的随即数</returns>
public static string GenerateRandomCode(int codeLength)
{
List<char> codes = new List<char>();

//初始化集合,0到9十个数字
for (int i = 0; i < 10; i++)
{
codes.Add((char)(i + '0'));
}

Random random = new Random();
char[] randomCode = new char[codeLength];//定义字符数组存放生成的随即码
for (int i = 0; i < randomCode.Length; i++)
{
randomCode[i] = codes[(int)(codes.Count * random.NextDouble())];//count指集合中实际的元素个数
codes.Remove(randomCode[i]);
}

return new string(randomCode);
}
}
}
suyiming 2008-07-09
  • 打赏
  • 举报
回复
如果是用到 Random 函数就有重复 这个是绝对,因为Random 本身也是个算法,不是随机的,如果当时间间隔非常短的时候,抽取重复的几率是100%
所以要彻底避免重复,只能用个方法去防止,这里我可以介绍递归算法。
 Random ra=new Random(unchecked((int)DateTime.Now.Ticks));
  int[] arrNum=new int[10];
  int tmp=0;
  int minValue=1;
  int maxValue=10;
  for (int i=0;i<10;i++)
  {
    tmp=ra.Next(minValue,maxValue); //随机取数
    arrNum=getNum(arrNum,tmp,minValue,maxValue,ra); //取出值赋到数组中
  }
  .........
  .........
  public int getNum(int[] arrNum,int tmp,int minValue,int maxValue,Random ra)
  {
    int n=0;
    while (n<=arrNum.Length-1)
    {
      if (arrNum[n]==tmp) //利用循环判断是否有重复
      {
        tmp=ra.Next(minValue,maxValue); //重新随机获取。
        getNum(arrNum,tmp,minValue,maxValue,ra);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
      }
    n++;
    }
    return tmp;
  }
nattystyle 2008-07-09
  • 打赏
  • 举报
回复

public int getNum()
{
string s = "";
Random ra = new Random();
while (s.Length != 4)
{
string st = (ra.Next(0, 9)).ToString();
if (!s.Contains(st))
s += st;
}
int i = Convert.ToInt32(s);
return i;
}
家鸣 2008-07-09
  • 打赏
  • 举报
回复
随机取数本来就不保证唯一,你现在只是在0-9选数,这样选到同一个数的几率就有1/10, 你要每次都不一样,随机取数不是理想解决方法。你不如搞个变量,每次自增1好了。或者用Guid生成唯一的标识。
Magic_YJL 2008-07-09
  • 打赏
  • 举报
回复
这种方法不仅效率低,而且实现不了生成不重复的随即数,建议楼主换思路
qqqq6119 2008-07-09
  • 打赏
  • 举报
回复
1楼和2楼朋友的办法我测试了下,还是存在相同数字问题。
qqqq6119 2008-07-09
  • 打赏
  • 举报
回复
还是存在相同数字问题并且不是偶然。
家鸣 2008-07-09
  • 打赏
  • 举报
回复
应该是值传递引起的问题,getNum改成引用传递。

public string getRandomNum()
{
string[] arr = new string[4];
int[] arrNum = new int[4];
Random ra = new Random();
int tmp = 0;
for (int i = 0; i <= 3; i++)
{
tmp = ra.Next(0, 9); //随机取数
arrNum[i] = getNum(arrNum, tmp, ref ra,i); //取出值赋到数组中
arr[i] = Convert.ToString(arrNum[i]);
}

string qwer = arr[0] + arr[1] + arr[2] + arr[3];
return qwer;
}
public int getNum(int[] arrNum, int tmp, ref Random ra,int i)
{
int n = 0;
while (n <= i - 1)
{
if (arrNum[n] == tmp) //利用循环判断是否有重复
{
tmp = ra.Next(0, 9); //重新随机获取。
getNum(arrNum, tmp, ref ra,i);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
}
n++;
}
return tmp;
}
kkun_3yue3 2008-07-09
  • 打赏
  • 举报
回复
Random ra = new Random();

把这一行提到方法外,在方法内引用一直使用.Next()方法就不会出现重复随机数或很少出现重复随机数

private Random ra = new Random();
public string getRandomNum()
{
string[] arr = new string[4];
int[] arrNum = new int[4];
int tmp = 0;
for (int i = 0; i <= 3; i++)
{
tmp = ra.Next(0, 9); //随机取数
arrNum[i] = getNum(arrNum, tmp, ra,i); //取出值赋到数组中
arr[i] = Convert.ToString(arrNum[i]);
}

string qwer = arr[0] + arr[1] + arr[2] + arr[3];
return qwer;
}
public int getNum(int[] arrNum, int tmp, Random ra,int i)
{
int n = 0;
while (n <= i - 1)
{
if (arrNum[n] == tmp) //利用循环判断是否有重复
{
tmp = ra.Next(0, 9); //重新随机获取。
getNum(arrNum, tmp, ra,i);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
}
n++;
}
return tmp;
}
bbbbbb888888 2008-07-09
  • 打赏
  • 举报
回复
主要来mark8楼的代码的

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧