我正在编写一个应该作为彩票的代码。可用的彩票号码是1-50,其中有10个。用户应输入一个号码,如果用户的号码与10个随机抽奖号码中的一个匹配,则程序返回。我已经把所有这些部件都搞定了,但是有一个问题;所有10个彩票号码必须是唯一的。我有10个独特的数字1-50,但它们并非随机。我写到这一点的代码对我来说似乎是正确的,除了我知道有些东西丢失了(以及我可以清理我的代码的事实,但我现在正专注于目标)。现在,如果我运行该程序,它将返回十个零。我需要彩票阵列中的每个元素都是1-50的唯一数字,并且每次运行程序时都会生成不同的数字集。任何帮助将不胜感激。
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using std::cout; using std::cin; using std::endl;
void printOut(int[]);
void draw(int[]);
bool check();
int fillFunc[10];
int main()
{
const int arraySize = 10;
int win[arraySize] = {};
srand((unsigned)time(NULL));
draw(win);
cout << "Your lottery numbers are: ";
printOut(win);
}
void draw(int fillFunc[])
{
int i;
for (i = 0; i < 10; i++)
{
if (check() == true)
continue;
fillFunc[i] = 1 + rand() % 50;
}
}
void printOut(int fillFunc[])
{
for (int i = 0; i < 10; i++)
{
cout << " " << fillFunc[i];
}
cout << "\n";
}
bool check()
{
for (int i = 0; i < 10; ++i)
{
if (fillFunc[i] == i)
return true;
}
return false;
}
(也不要问我为什么数组有名称&#34; win&#34;,这是我的教授要我称之为的)
答案 0 :(得分:1)
要回答您在评论中更新的问题,您需要考虑改组算法。
我会告诉你如何做到这一点,这是O(n)所以你不必循环&#34;循环&#34;通过您当前的数字列表,并继续检查新号码是否已被选中......
你的彩票最大数量是50,所以制作一个大小为50的数组,如下所示:
选择一个号码放入&#34;选择&#34;数字数组...
indexToLotteryNumbers = rand() % 50 - numbersPickedSoFar;
randomLotteryNumber[i++] = lotteryNumber[ indexToLotteryNumbers ];
// this is the key "trick"
swap(&lotteryNumber[ indexToLotteryNumbers ], &lotteryNumber[49-numbersPickedSoFar]);
numbersPickedSoFar++;
理论
看一个小例子......说你有1 2 3 4
rand()
生成&#34; 2&#34; rand()
生成&#34; 1&#34;所以你的号码是&#34; 1&#34;然后你用&#34;外部&#34;交换它未命中的数字3 4 | 1 2 rand()
生成我希望这是有道理的。
答案 1 :(得分:1)
因为check()
始终返回true
。在开始时,数组用零填充,因此check
将true
作为win[0]==0
返回,并且永远保持为真,因为没有任何更改该值。因此,在draw
中,您始终会转移到continue
并且永远不会修改任何内容。
要解决这个问题,可以采用一种方法来改变1-50的序列,并提取混洗数组的前10个值。您可以使用非常简单的Fisher-Yates algorithm。
答案 2 :(得分:0)
当fillFunc[i]
为10时,您只为i
分配一个值,这是一个超出范围的访问权限。将作业移动到循环内部。
你也有其他问题。如果执行continue
,则只需在数组中保留一个条目。
您应该尝试在程序中添加大量输出语句,以便更轻松地了解它正在做什么。如果您愿意,可以使用调试器逐步完成它。
答案 3 :(得分:0)
考虑到你的限制,这就是我要做的。在填充数组时,不要检查数字是否唯一,只需将数组传递给选择数字的函数,以便它可以返回唯一值。
我还删除了冗余的全局数组。如果您忘记将正在使用的本地数组传递给任何函数,它可能是错误的来源。
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int getUniqueNumber(int fillFunc[])
{
while(true)
{
//pick number
int val = 1 + rand() % 50;
//assume it's unique
bool unique = true;
for (int i = 0; i < 10; ++i)
{
//if another number matches, it isn't unique, choose again
if (fillFunc[i] == val)
{
unique = false;
break;
}
}
//if it is unique, return it.
if (unique)
{
return val;
}
}
//never reached, but avoids an all control paths must return a value warning.
return -1;
}
void draw(int fillFunc[])
{
for (int i = 0; i < 10; i++)
{
fillFunc[i] = getUniqueNumber(fillFunc);
}
}
void printOut(int fillFunc[])
{
for (int i = 0; i < 10; i++)
{
cout << " " << fillFunc[i];
}
cout << "\n";
}
int main()
{
srand((unsigned)time(NULL));
const int arraySize = 10;
int win[arraySize] = {};
draw(win);
cout << "Your lottery numbers are: ";
printOut(win);
return 0;
}
还有其他一些可能更好的方法来选择范围内的唯一数字,但我只是简单地实现和解释。您可以在这些问题中阅读其他一些方法:
Unique random numbers in an integer array in the C programming language