尝试使用随机数生成多个数组,但每次都获得相同的数组

时间:2017-11-03 03:27:49

标签: visual-c++ random

我试图模拟从1-36随机挑选数字,并查看我需要多少时间来挑选所有不同的36号码。如果我总共挑选了10个重复的号码,我可以选择一个未被挑选的号码,并重新计算重复次数。 无论如何,如果我只创建一个包含随机数的数组,我的代码工作正常。但是我在整个过程之外添加一个for循环并重复100次以便平均找出我需要多少时间。并且代码创建了100个相同的数组。

    #include "iostream"
    #include "stdlib.h"
    #include "time.h"

    using namespace std;

    class Lottery
    {
    private:
        int PickNonExistingNum()//pick a number that's not in num
        {   
            int pick;   
            pick = RandomNumber();
            for (int m = 0; m < 36; m++)
            {
                if (pick == num[m])
                {
                    pick = RandomNumber();
                    m = 0;
                    continue;
                }
            }
            return pick;
        }

    public:
        int check;
        int TimeOfPicking = 0;      //how many time we pick a number
        int num[36] = { 0 };        //array contains all the number
        bool same = false;          //flag that indicates consistency
        int accum = 0;              //how many time we pick a same number, when reach 10 we pick again
        bool IsRandomSeeded = false;

        int i = 0;                  //used to change i value in for loop of main loop

        int RandomNumber()//generate a number from 1 to 36
        {
            int number;
            number = rand() % 36 + 1;
            return number;
        }

        bool CheckExistingNum()
        {
            for (int k = 0; k < 36; k++)
            {
                if (check == num[k])
                {
                    if (accum < 10)//add 1 to accum each time when there's a same number
                    {
                        i--;
                        accum++;
                        same = true;
                        break;
                    }
                    else if (accum == 10)//pick again when accum reach 10
                    {
                        num[i] = DoubleCheckPick(PickNonExistingNum());
                        accum = 0;
                        same = true;
                        break;
                    }
                }
            }
            return same;
        }

        void Picking()
        {
            for (i; i < 36; i++)//finish the loop when player had picked all 36 numbers
            {
                check = RandomNumber();//give check a random value between 1 and 36
                TimeOfPicking++;    //add 1 time to the total time of picking
                same = false;       //set flag to false

                if (!CheckExistingNum())//give checked value to num if there's no same number
                {
                    num[i] = check;
                }
            }

            cout << "Pick " << TimeOfPicking << " time" << endl;//show results
            cout << "the numbers are:" << endl;
            for (int m = 0; m < 36; m++)
            {
                cout << num[m] << ", ";
            }
            cout << endl;
        }

        bool DoubleCheck()
        {
            for (int m = 0; m < 36; m++)
            {
                for (int k = m + 1; k < 36; k++)
                {
                    if (num[m] == num[k])
                    {
                        cout << "there's a same number: " << num[m] << endl << endl;
                        return false;
                    }
                }
            }
            cout << "no same number" << endl << endl;
            return true;
        }

        int DoubleCheckPick(int check)
        {
            for (int m = 0; m < 36; m++)
            {
                if (check == num[m])
                {
                    check = PickNonExistingNum();
                    m = 0;
                    continue;
                }
            }
            return check;
        }

        void reset()//reset all the value for multiple process
        {
            int TimeOfPicking = 0;      //how many time we pick a number
            int num[36] = { 0 };        //array contains all the number
            int same = false;           //flag that indicates consistency
            int accum = 0;              //how many time we pick a same number, when reach 10 we pick again
            int check = 0;

            int i = 0;                  //used to change i value in for loop of main loop
        }

    };


    int main()
    {   
        Lottery Num;

        //int t = 0;

        srand(time(NULL));              //set random generator

        int PickingTime[100] = { 0 };//an array contains all 100 times of data
        double sum = 0;              //the sum of all the data

        for (int i = 0; i < 100; i++)//run the program 100 times
        {
            cout << "the " << i + 1 << " process" << endl;

            int wait = clock();
            while (clock() <= (wait + 1000));//delay for 3000 unit time 

            Num.reset();
            Num.Picking();
            if (!Num.DoubleCheck())//if there's a same number
            {
                cout << "fail process" << endl;
                i--;            //redo the process
                continue;
            }
            else
            {
                PickingTime[i] = Num.TimeOfPicking;
            }
        }

        for (int i = 0; i < 100; i++)
        {
            sum += PickingTime[i];
        }

        cout << "the average picking time in 100 test is: " << sum / 100 << endl;

        return 0;
    }

,结果如下result 所有数组都是一样的。我想这可能是rand()问题,但我无法找到任何可行的解决方案。

1 个答案:

答案 0 :(得分:0)

您的reset()函数实际上没有重置类变量 - 它定义了新的本地变量。因此,后来对Picking()的调用没有为i执行任何操作36。将其更改为以下内容:

void reset()//reset all the value for multiple process
{
    TimeOfPicking = 0;      //how many time we pick a number
    //int num[36] = { 0 };  //No need to reset the array - it will be overriden in the later invocation of Picking()
    same = false;           //flag that indicates consistency
    accum = 0;              //how many time we pick a same number, when reach 10 we pick again
    check = 0;

    i = 0;                  //used to change i value in for loop of main loop
}

每次都会得到不同的数字序列。

请注意,您的CheckExistingNum()也必须修复才能发挥作用 - 将for (int k = 0; k < 36; k++)更改为for (int k = 0; k < i; k++),只检查当前循环中生成的数字,而不是旧数字。这是必需的,因为我们不会在num中重置reset()(要将其设置为除初始化以外的任何其他位置,您必须使用循环或memset())。它还可以使您的程序更快。

在2次修复之后,我得到了以下输出,

......
the 98 process
Pick 76 time
the numbers are:
26, 9, 4, 36, 32, 12, 16, 7, 17, 33, 1, 10, 18, 2, 23, 21, 28, 29, 30, 25, 8, 34, 27, 31, 14, 24, 11, 20, 6, 22, 3, 15, 19, 5, 13, 26,
there's a same number: 26

fail process
the 98 process
Pick 76 time
the numbers are:
17, 3, 15, 7, 31, 12, 26, 24, 9, 13, 4, 32, 29, 11, 20, 14, 23, 1, 33, 18, 8, 27, 21, 19, 25, 6, 30, 36, 2, 5, 28, 34, 22, 35, 16, 10,
no same number

the 99 process
Pick 106 time
the numbers are:
10, 11, 9, 28, 36, 15, 18, 8, 13, 34, 30, 3, 12, 21, 16, 1, 2, 27, 19, 23, 17, 5, 20, 14, 4, 25, 6, 29, 7, 22, 33, 26, 32, 24, 31, 35,
no same number

the 100 process
Pick 106 time
the numbers are:
15, 23, 22, 11, 5, 35, 2, 26, 21, 4, 3, 33, 28, 19, 1, 14, 7, 29, 24, 32, 8, 12, 13, 27, 10, 17, 34, 18, 16, 6, 25, 20, 31, 36, 30, 9,
no same number

试一试!您可以进一步优化程序,这是一个练习。 :)