抽奖算法T_T,排除抽过的数字
写了个简单的抽奖功能,但是发现会抽取到重复数字,如何做才好?
private void btn_start_Click(object sender, EventArgs e) { //开始抽奖 if (btn_start.Text == "停止") { timer1.Stop(); btn_start.Text = "开始"; //保存获奖信息 SaveResult(); } else { cjnum++; timer1.Start(); } } private void SaveResult() { TGH.Lib.Log.WriteFile(Application.StartupPath + "\\choujiang.txt", "第" + cjnum.ToString() + "次抽奖数为:" + lbl_num.Text); lbl_result.Text += "第" + cjnum.ToString() + "次抽奖号码为:" + lbl_num.Text;// +"\r\n"; } public int[] getRandomNum(int num, int minValue, int maxValue) { Random ra = new Random(unchecked((int)DateTime.Now.Ticks)); arrNum = new int[num]; int tmp = 0; for (int i = 0; i <= num - 1; i++) { tmp = ra.Next(minValue, maxValue); //随机取数 arrNum[i] = ChouJiang(arrNum, tmp, minValue, maxValue, ra); //取出值赋到数组中 } return arrNum; } private int ChouJiang(int[] cjresults, int tmp, int minnum, int maxnum, Random ra) { int i = 0; xunhuannum++; while (i <= cjresults.Length - 1) { if (cjresults[i] == tmp) { //重新随即获取 tmp = ra.Next(minnum, maxnum); //递归:如果取出来的数字和已取得的数字有重复就重新随机获取 ChouJiang(cjresults, tmp, minnum, maxnum, ra); } i++; } return tmp; } private void timer1_Tick(object sender, EventArgs e) { //从fw1至fw2中取出6个互不相同的随机数 int[] arr = getRandomNum(cjtype, fw1, fw2); int i = 0; string temp = ""; while (i <= arr.Length - 1) { temp += arr[i].ToString() + "\n"; i++; } btn_start.Text = "停止"; lbl_num.Text = temp; }
/// <summary> /// 生成最大值范围内无重复值的长度为最大值的随机序列,例:6,则返回0,1,2,3,4,5 的List /// </summary> /// <param name="maxValue"></param> /// <returns></returns> public static List<int> GetRandomList(this int maxValue) { if (maxValue == 0) { return null; } //逻辑描述:生成从0开始到maxValue的tempList //然后random一次就maxValue--,并将random出来的整数用做索引,加入到returnList并从tempList中移除 maxValue = Math.Abs(maxValue);//防止负数 List<int> tempList = new List<int>(); for (int i = 0; i < maxValue; i++) { tempList.Add(i); } Random rd = new Random(); List<int> returnList = new List<int>(); while (maxValue > 0) { int tempInt = 0; if (maxValue > 1)//当maxValue为1时,不再进行随机,因为还剩一个数字,无需随机 { tempInt = rd.Next(maxValue); } returnList.Add(tempList[tempInt]); tempList.RemoveAt(tempInt); maxValue--; } return returnList; }
[解决办法]
http://topic.csdn.net/u/20111117/12/f59bad6f-a3e3-43a6-a571-1054a7869d8b.html
[解决办法]
抽过的数字放入一个 list 变量,然后下次抽取,判断 list 里面有没有,如果有的话,那就再抽一次,知道没有抽过的位置。
[解决办法]
// 修正!!
// 抽奖范围int range = 100;// 抽奖个数int lotteryNum = 10;// 中奖号码List<int> l = new List<int>();Random r = new Random();while (l.Count != lotteryNum){ int n = r.Next(1, range); if (l.Contains(n)) continue; l.Add(n);}// 拿着话筒,公布抽奖名单吧PublishLotteryNumbers();
[解决办法]
先把所有的数放在一个线性表里面,然后随机乱序取前N个不就好了么。 这是双色球……
有重复的也行,那是七星彩。
[解决办法]
关于生成1-20随机数,生成10个,不能重复 LINQ写法
var num = Enumerable.Range(1, 20)
.Select(x => new { v = x, k = Guid.NewGuid().ToString() }).ToList()
.OrderBy(x => x.k)
.Select(x => x.v)
.Take(10).ToList();
foreach (var i in num)
{
Console.WriteLine(i);
}
[解决办法]
用链表实现
Random rad = new Random(); //随机数 LinkedList<int> list; //链表 LinkedListNode<int> node; //当前链表指针 public void initialize() { //初始化 list = new LinkedList<int>(100); //构造链表 //todo 往链表中插入数据 从1到100 for (int i = 1; i < 101; i++) { list.AddLast(i); } node = list.First; //初始指针 } public int GetRandomValue() { node = GetRandomNode(rad.Next(1, 100)); //根据随机值取节点 return node.Value; //返回节点值 } public LinkedListNode<int> GetRandomNode(int x) { int i = 0; while(i ++ < x) { node = node.Next ?? list.First; } //指针移动x次,循环从头开始。 list.Remove(node); //把节点从链表中移除 return node; }
[解决办法]