防止重复随机创建的相同数字

时间:2014-01-03 20:42:26

标签: c random

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main (void) {

    int i,j,z,w,c; /* counter*/
    int ticket[6],n[6];
    int a; /*numbers of one ticket*/
    int x; /* Random numbers of tickets*/
    int num; /*Quantity of tickets*/
    int loser = 0; /*initialize the number of known-tickets*/
    int threeknown = 0;
    int fourknown = 0;
    int fiveknown = 0;
    int winner = 0;


    srand (time(NULL));


    printf ("Please enter the lucky ticket numbers between 0 and 50\n");

    for (i=0;i<6;i++) { /* loop for entering numbers of ticket from keyboard*/
        scanf ( "%d",&a);
        if (a<50 && a>0){
        ticket[i] = a;
        }
        else {
             printf ("\a ERROR: Please enter number between 0 and 50\n");
             i--; /* enter again */
        }
        }
    printf ("Lucky ticket is:\n");
    for (i=0;i<6;i++) {
        printf ("%3d",ticket[i]);
        }
        printf ("\n");
    printf ("Please enter the quantity of tickets\n\a");
    scanf ("%d",&num);
    for (z=0;z<num;z++) {  /* For each ticket */
        for (j=1;j<=6;j++) {
            x = 1 + rand()%49;
            n[j] = x;
            printf ("%3d",n[j]);
            }

            printf("\n\n");
            }
    for (z=0;z<num;z++){  /*counter for each ticket control */
        if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2] && ticket[3]==n[3] && ticket[4]==n[4] && ticket[5]==n[5]) {
                            winner += 1;
                            }
        if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2] && ticket[3]==n[3] && ticket[4]==n[4]) {
                            fiveknown += 1;
                            }
        if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2] && ticket[3]==n[3]) {
                            fourknown += 1;
                            }
        if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2]) {
                            threeknown += 1;
                            }
        else {
             loser += 1;
             }
                             }
        printf ("Number of winners : %d\n",winner);
         printf ("Number of five-knowns : %d\n",fiveknown);
          printf ("Number of four-knowns : %d\n",fourknown);
           printf ("Number of three-knowns : %d\n",threeknown);
              printf ("Number of losers : %d\n",loser);


        system ("PAUSE");
        return 0;

        }

我有关于C编码宾果游戏程序的项目。我需要在0到50之间保持键盘的赢家票(12 34 23 11 47 4),然后我需要随机生成票。在这些票中,没有一个具有相同的号码,并且排序并不重要。例如(23 12 10 4 9 46)。我的问题是如何获得这些门票?我不想要这种票(12 43 20 12 9 4)

2 个答案:

答案 0 :(得分:3)

构建50个可接受值的数组,选择一个,然后将其从数组中删除。

由于数组中的顺序并不重要,因此可以通过用最后一个值覆盖它并减少“数组计数”变量来以低成本删除它。

void RemoveFromArray(int* arr, size_t *pNumberOfElements, size_t indexToRemove)
{
    //Note: I'm not putting the error/bounds checking because it's not what the question is about.
    size_t indexLast = *pNumberOfElements - 1;
    arr[indexToRemove] = arr[indexLast];
    (*pNumberOfElements)--;
}

void ChooseRandom6of50(int* random6ints)
{
    int arr[50];
    size_t nElements = 50;
    {
        size_t i;
        for(i=0 ; i<50 ; i++)
            arr[i] = (int)(i+1); //Fill with values 1 to 50
    }
    {
        size_t iDest;
        for(iDest=0 ; iDest<6 ; iDest++)
        {
            int rnd = rand() % nElements; //The real code should use the more elaborate random formula
            size_t randIndex = rnd;
            random6ints[iDest] = arr[randIndex];
            RemoveFromArray(arr, &nElements, randIndex);
        }
    }


}

答案 1 :(得分:0)

对于少数选择的门票,最简单的方法是随机抽取门票,但如果门票已经在抽签的批次中,则再次抽奖:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX

int contains(int ticket[], int n, int which)
{
    while (n-- > 0) {
        if (ticket[n] == which) return 1;
    }
    return 0;
}

void draw(int ticket[], int n, int m)
{
    int i, t;

    if (n > m) return;

    for (i = 0; i < n; i++) {
        do {
            t = rand() % m;
        } while (contains(ticket, i, t));
        ticket[i] = t;
    }
}

int main (void)
{
    int ticket[6];
    int i;

    draw(ticket, 6, 50);
    for (i = 0; i < 6; i++) printf("%4d", ticket[i]);
    printf("\n");

    return 0;
}

请注意,如果要绘制的门票数draw大于可用门票n,则m功能不会执行任何操作,因为这会导致无限环。如果n == m抽签就像洗牌一样,虽然效率非常低。 (在这种情况下,draw函数可能应该返回错误代码或中止程序,但是为了简单起见,我已经把它留了出来。)

如果您想将用户的门票与抽奖进行比较,contains功能也会派上用场。 (此外,如果您可以将变量threeknownfiveknown等转换为数组hits[7],它看起来更像编程。)