Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Losowanie bez powtórzeń - losowanie ze zbioru znajdującego się w tablicy

Ostatnio zmodyfikowano 2016-11-27 12:40
Autor Wiadomość
SilentWolf
Temat założony przez niniejszego użytkownika
[C++] Losowanie bez powtórzeń - losowanie ze zbioru znajdującego się w tablicy
» 2016-11-26 10:41:54
Witam, mam pytanie odnośnie funkcji odpowiedzialnej za losowanie liczb. Jak widać w poniżej zamieszczonym kodzie, do wylosowania 3 liczb użyłem "sztywno" wpisanego przedziału liczb przy pomocy cyfry '3'. Chciałbym się dowiedzieć czy jest możliwe aby określić przedział, z którego będą losowane liczby przy pomocy tablicy, w której znajdują się wypisane liczby, aby przy zadaniu nr 2 nie musieć nic poprawiać w funkcji odpowiedzialnej za losowanie? Próbowałem to zrobić na 2 sposoby jakie mi przyszły do głowy jednak za każdym razem program losował liczby spoza tablicy.

Drugą rzeczą o którą chciałbym zapytać to co mógłbym w poniższym kodzie poprawić tak by był czytelniejszy i krótszy, mając na uwadze, że nie chciałbym wychodzić poza zakres przedstawiony w kursie do tej pory, czyli do użytku mając jedynie pętle do...while, warunek if...else, funkcje oraz tablice jednowymiarowe. Ważnym dla mnie jest by zachować poziom zabezpieczeń, który jest obecnie w kodzie aby nie można było pracować na niewłaściwych danych lub danych powtarzających się.

Ostatnie pytanie jakie mam to, dlaczego tym razem do wypisania prawidłowych liczb przy użyciu funkcji wypisz, niewystarczające było użycie jedynie tablicy zawierającej wylosowane liczby, potrzebna była także tablica z wpisanymi liczbami. Czy może jednak dało się to zrobić?
Z góry dziękuje za odpowiedzi i wszystkie wskazówki.

C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>

int wylosuj()
{
    return(( std::rand() % 3 ) );
}

bool czySiePowtarza( int iLiczba, int tablica[], int rozmiar )
{
    if( rozmiar <= 0 )
         return false;
   
    int licznik = 0;
    do
    {
        if( tablica[ licznik ] == iLiczba )
             return true;
       
        licznik++;
    } while( licznik < rozmiar );
   
    return false;
}

void wczytaj( int tablica[] )
{
    int licznik = 0;
    int rozmiar = 3;
    int wpisana;
    bool sukces;
    std::cout << "Podaj " << rozmiar << " liczby: " << std::endl;
    do
    {
        do
        {
            std::cin >> wpisana;
            sukces = std::cin.good();
            if( sukces == 0 )
            {
                std::cin.clear();
                std::cin.sync();
                std::cout << "Podaj inna liczbe: ";
            }
        } while( sukces == 0 );
       
        if( czySiePowtarza( wpisana, tablica, licznik ) == false )
        {
            tablica[ licznik ] = wpisana;
            licznik++;
        }
        else
        {
            std::cin.clear();
            std::cin.sync();
            std::cout << "Podana liczba sie powtarza. Wpisz inna: ";
        }
    } while( licznik < rozmiar );
   
}

void wypisz( int tablica_1[], int tablica_2[] )
{
    int licznik = 0;
    int rozmiar = 2;
    std::cout << "Wylosowane liczby to: ";
    do
    {
        std::cout << tablica_1[ tablica_2[ licznik ] ] << ", ";
        licznik++;
    } while( licznik < rozmiar );
   
}

int main()
{
    srand( time( NULL ) );
    int rozmiar_wylosowanych = 2;
    int wpisane_liczby[ 3 ];
    int wylosowane_liczby[ 2 ];
    int wylosowanych = 0;
   
    wczytaj( wpisane_liczby );
    do
    {
        int liczba = wylosuj();
        if( czySiePowtarza( liczba, wylosowane_liczby, wylosowanych ) == false )
        {
            wylosowane_liczby[ wylosowanych ] = liczba;
            wylosowanych++;
        }
    } while( wylosowanych < rozmiar_wylosowanych );
   
    wylosowanych = 0;
    wypisz( wpisane_liczby, wylosowane_liczby );
    return 0;
}
P-154146
karambaHZP
» 2016-11-27 00:37:37
Chciałbym się dowiedzieć czy jest możliwe aby określić przedział, z którego będą losowane liczby
Czy wiesz jak działa funkcja
rand()
? Jeśli tak do twojej funkcji losującej
int wylosuj() { }
 dodaj dwa argumenty
określające dolną i górną granicę przedziału. Wyliczenie to już kwestia dodawania i odejmowania.

Możesz też skorzystać z <random>:
Frazy, które należy wpisać w wyszukiwarkę google:
P-154165
SilentWolf
Temat założony przez niniejszego użytkownika
» 2016-11-27 12:24:01
Dziękuje za odpowiedź. Spróbuje zrobić to sposobem, który podałeś i poczytam linki odnośnie <random>. Pytałem o to bo myślałem, że funkcja losująca mogłaby wyglądać tak:
C/C++
int wylosuj( int tablica[] )
{
    return( std::rand() % tablica );
}
 
Jednak powyższy przykład w ogóle się nie kompilował, więc wymyśliłem jego dwie modyfikacje które się kompilowały, jednakże w pierwszym przypadku program losował liczby nieznajdujące się w tablicy a w drugim przypadku kiedy miał wypisać wylosowane liczby wyskakiwało okienko "Program przestał działać".

Drugą część zadania czyli zwiększenie ilości wpisanych liczb do 10, a losowanych do 8, chcę spróbować wykonać przez zwiększenie liczby elementów w obydwu tablicach wykorzystując funkcję dopisz, przedstawioną w rozdziale 20 i byłem ciekawy czy da się to zrobić tak by nie modyfikować przy tym funkcji odpowiedzialnej za losowanie.
P-154180
karambaHZP
» 2016-11-27 12:40:45
C/C++
int wylosuj( int tablica[] )
{
    return( std::rand() % tablica );
}
Tutaj jako wartość dzielenia modulo użyłeś wskaźnika na pierwszy element tablicy.

Pytałem o to bo myślałem, że funkcja losująca mogłaby wyglądać tak:
Funkcja losująca rand() losuje liczby z konkretnego przedziału, a otrzymanie oczekiwanego wyniku
zależy od operacji matematycznych na zwróconej wartości z funkcji rand().
Użyj zwróconej wartości z funkcji wylosuj() jako indeks dla tablicy liczb i zapamiętaj ten wynik,
aby można było później sprawdzić czy taki indeks był wcześniej wylosowany.
P-154181
« 1 »
  Strona 1 z 1