Матрица със случайни числа от 1 до 52, които не се повтарят, но винаги се повтаря 1 число

Кодирам проект на C и се опитвам да създам матрица със случайни числа от 1 до 52, които не се повтарят, но продължават да повтарят винаги 1 число!

void baralhar(int b[]){
int x,y,r;
for(x=0;x<53;x++){
    r=rand() % 52+1;

    for(y=0;y<=x;y++){
        if(r==b[y])
        {
            y=0;
            r=rand() % 52+1;
        }
    }
    b[x]=r;
}

}

Изход: 49 2 3 23 15 50 29 12 33 37 6 21 9 16 14 38 41 31 36 10 39 43 40 30 48 7 4 8 5 18 34 46 1 47 27 13 51 42 17 19 25 20 4298 525 35 24 32 22 44

в този пример можете да видите, че числото 49 се повтаря. Можете ли да помогнете тук?


person durooo    schedule 10.01.2014    source източник
comment
Това, от което се нуждаете, е масив от числа от 1 до 52, който след това се разбърква. Прочетете за разбъркване на алгоритми, напр. en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle.   -  person PiotrK    schedule 11.01.2014
comment
нека позная, правиш ли нещо свързано с карти?   -  person Derek    schedule 11.01.2014
comment
Съгласете се с разбъркване вместо избиране на числа; но също така изглежда, че сте отклонени с 1? Изглежда се опитвате да запълните слотове 0-52 с числата 1-52, така че едно от тях ще трябва да се повтори. Вашият масив трябва да е с размер 52, което означава слотове 0-51.   -  person tabstop    schedule 11.01.2014
comment
Кристална топка: Отговорът на следващия въпрос е stackoverflow.com/questions/3067364/   -  person chux - Reinstate Monica    schedule 11.01.2014
comment
stackoverflow.com /questions/20940694/   -  person BLUEPIXY    schedule 11.01.2014


Отговори (4)


Благодаря за това. сега мога да започна да разбера как работи всичко!
person gnometorule    schedule 10.01.2014
comment
Вие, сър, сте гений :D толкова очевидна грешка и не можах да я намеря, много благодаря - person durooo; 11.01.2014

Първо трябва да генерирате поредица от числа от 1 до 52 и след това да ги разбъркате. Това гарантира, че няма дубликати.

Следният код използва алгоритъм за разбъркване на Fisher-Yates.

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

int main(void)
{
    int numbers[52];
    int i, j, temp;
    srand(time(NULL));

    // putting numbers from 1 to 52 into the 'numbers' array
    for(i=0; i<52; i++)
        numbers[i] = i + 1;

    // shuffling using Fisher-Yates shuffle algorithm
    for(i=51; i>=1; i--)
    {
        // very important: pick a random number from 1 to i
        j = rand()%(i+1);

        // swapping two numbers
        temp = numbers[i];
        numbers[i] = numbers[j];
        numbers[j] = temp;
    }

    // printing the array
    for(i=0; i<52; i++)
        printf("%d, ", numbers[i]);

    return 0;
}

Ето демонстрация: http://ideone.com/T5AXkM и ето хубаво обяснение стъпка по стъпка как алгоритъмът работи: http://www.youtube.com/watch?v=tLxBwSL3lPQ.

person PiotrK    schedule 10.01.2014
comment
+1 Подобно на цитата на Fisher-Yates, но предпочитайте отвътре навън - person chux - Reinstate Monica; 11.01.2014
comment
Благодаря, че ми даде идея как да започна да правя подредена матрица и след това как да я разбъркам. Браво - person durooo; 11.01.2014

Първо, вътрешният цикъл (за y) проверява "предишните" елементи на масива от b[0] до b[x]. Но елемент b[x] не е инициализиран в този момент. Той съдържа стойност за боклук (или каквото и да е било в b първоначално). Няма смисъл да сравняваме r с b[x]. Вашият вътрешен цикъл трябва да спре проверката на b[x - 1].

Второ, както вече беше споменато в другия отговор, след нулиране на y на 0, y незабавно се увеличава от цикъла. Така че през повечето време вашият код игнорира b[0], когато проверява за повторения.

Трето, вашият rand() % 52 + 1 израз може да генерира само 52 уникални числа, докато вашият код е написан да генерира 53. Вашият код трябва да се зацикля завинаги. (Не се зацикля вечно поради втория бъг). В заглавието на вашия въпрос казахте, че имате нужда от 52 номера. Защо тогава вашият външен цикъл е написан да прави 53 итерации?

person AnT    schedule 10.01.2014

void baralhar(int b[])
{

int x,y,r;

for(x=0;x<52;x++)

{
      r=rand() % 52+1;
      for(y=0;y<=x;y++)
      {
            if(r==b[y])
            {
                 y=-1;
                 r=rand() % 52+1;
            }
      }
      b[x]=r;
}

Просто променете в първия цикъл на "for(x=0;x‹52;x++)

и вместо да нулирате y=0, направете го y=-1

това ще реши втория и третия проблем от предишния коментар

тогава първото притеснение ще изчезне автоматично..

person h4ck3r    schedule 18.06.2015