• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[BUG] losowye cyfyr z danego przedzialu bez powtarzania, - ansi C

Object Storage Arubacloud
0 głosów
178 wizyt
pytanie zadane 21 listopada 2017 w C i C++ przez kappa997 Nowicjusz (230 p.)
edycja 21 listopada 2017

Witam, chce zrobic programik ktory losuje 5 cyfr z przedzialu 1-49 i aby liczby sie nie powtarzaly, wszystko dziala ale czasem wyskakuja dziwne liczby spoza przedzialu 1-49
np. pokazane na tym screenie

 

 

Wiecie może gdzie być błąd w tym kodzie??

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

int main()
{
    srand(time(NULL));
    int los[10], k, maska[49], liczba;
    for(k=0;k<49;k++)
        maska[k]=1;

    printf("Wygenerowane cyfry to\n");
    for(k=0;k<10;){
        liczba=rand()%49+1;

        if(maska[liczba-1]==1)
            los[k]=liczba;
       maska[liczba-1]=0;
    k=k+1;
   }
    for(k=0;k<10;k++)
    printf("%d\n", los[k]);

    return 0;
}

shead: Kod był wrzucony w prawie dobre ramki, poprawiłem ;)

2 odpowiedzi

+1 głos
odpowiedź 21 listopada 2017 przez mokrowski Mędrzec (155,460 p.)
wybrane 21 listopada 2017 przez kappa997
 
Najlepsza

Zakres od 1 do 49 nie jest obszerny. Lepszym rozwiązaniem będzie więc:

  1. Stworzenie tablicy liczb i wypełnienie jej.
  2. Potasowanie tablicy z liczbami.
  3. Wybranie pierwszych 5 i wyświetlenie ich.

Teraz Twój kod wykonuje się niedeterministycznie. Jeśli "masz nieszczęście" losowania ciągle tych samych liczb, będzie wykonywał się długo.

Co do pkt. 2 proponowanego rozwiązania, wystarczy losować 2 indeksy tablicy i zamienić miejscami elementy :-)

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

void shake_table(int * table, size_t size) {
    srand((unsigned)time(NULL));
    for(size_t i = 0; i < size; ++i) {
        size_t first_index = rand() % size;
        size_t second_index = rand() % size;
        /* Swap value */
        int value = table[first_index];
        table[first_index] = table[second_index];
        table[second_index] = value;
    }
}

void fill_table(int * table, size_t size) {
    while(size--) {
        table[size] = size + 1;
    }
}

void show_elements(int * table, size_t size) {
    printf("Wylosowano %zu elementów:\n", size);
    for(size_t i = 0; i < size; ++i) {
        printf("%d ", table[i]);
    }
    puts("");
}

int main(void) {

    int table[49];
    size_t table_size = sizeof(table) / sizeof(table[0]);

    fill_table(table, table_size);
    shake_table(table, table_size);
    show_elements(table, 5);

    return EXIT_SUCCESS;
}

 

+1 głos
odpowiedź 21 listopada 2017 przez damianeqe Gaduła (4,380 p.)
Jeżeli wylosowałeś liczbę która już była, to nie powinieneś zwiększać k.
komentarz 21 listopada 2017 przez kappa997 Nowicjusz (230 p.)
to jak to powinno wyglądać bo nie mam pomyslu :(?
komentarz 22 listopada 2017 przez damianeqe Gaduła (4,380 p.)
Zwiększasz k jeżeli, liczba nie została wylosowana, to sprawdzasz w swoim if, jeżeli liczba się powtarza k powinno pozostać bez zmian. 

for(k=0;k<10;){
        liczba=rand()%49+1;
        if(maska[liczba-1]==1) {
            los[k]=liczba;
            maska[liczba-1]=0;
            k=k+1;
        }
   }

 

Podobne pytania

0 głosów
2 odpowiedzi 1,546 wizyt
0 głosów
1 odpowiedź 99 wizyt
pytanie zadane 22 października 2015 w C i C++ przez Waszek Gaduła (4,130 p.)
+1 głos
1 odpowiedź 236 wizyt
pytanie zadane 15 października 2015 w C i C++ przez Waszek Gaduła (4,130 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...