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

Lekcja 21 losowanie z podanych liczb

Ostatnio zmodyfikowano 2013-11-11 16:53
Autor Wiadomość
dawidrz
Temat założony przez niniejszego użytkownika
Lekcja 21 losowanie z podanych liczb
» 2013-11-11 02:13:15
Witam.
W zadaniu 1 z lekcji 21 pojawia się problem w czasie działania programu. Aplikacja ma wylosować 2 liczby z 3 podanych przez użytkownika. Program kompiluje się bez problemu i raz działa dobrze natomiast zdarza się, że czasem wylosuje liczbę całkowicie poza zakresem.

C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

bool czyWylosowana( int liczba, int t[], int ile )
{
    if( ile <= 0 )
         return false;
   
    int licznik = 0;
    do
    {
        if( t[ licznik ] == liczba )
             return true;
       
        licznik++;
    } while( licznik < ile );
   
    return false;
}

int wczytaj( int t[], int ile )
{
    cout << "podaj 3 liczby " << endl;
    int licznik = 0;
    do
    {
        cin >> t[ licznik ];
        licznik++;
    } while( licznik < ile );
   
}

int losowanie( int liczby[ 3 ] )
{
    int wylosowana =( rand() % 3 ) + 0;
   
    return liczby[ wylosowana ];
}

int main()
{
    srand( time( 0 ) );
    int liczby[ 3 ];
    int wylosowane[ 2 ];
    int licznik = 0;
   
    wczytaj( liczby, 3 );
    do
    {
        int wartosc = losowanie( liczby );
        if( czyWylosowana( wartosc, wylosowane, licznik ) == false )
             wylosowane[ licznik ] = wartosc;
       
        licznik++;
    } while( licznik < 2 );
   
    licznik = 0;
    cout << "wylosowano: " << endl;
    do
    {
        cout << wylosowane[ licznik ] << endl;
        licznik++;
    } while( licznik < 2 );
   
   
    return 0;
}
P-95980
pekfos
» 2013-11-11 10:11:58
Zwiększasz licznik niezależnie od tego, czy dopisałeś kolejną liczbę do tablicy wylosowanych. Poza tym, podejście do zadania jest złe.
P-95988
dawidrz
Temat założony przez niniejszego użytkownika
» 2013-11-11 12:07:23
Poprawiłem kod zgodnie z sugestią i pomogło.
Jeśli to nie będzie problem to czy mogę prosić o rozwinięcie "złego podejścia do zadania"?
Dzięki
P-96006
pekfos
» 2013-11-11 12:15:29
Zobacz, co Twój program zrobi, gdy user poda 3 takie same liczby ;)
P-96008
dawidrz
Temat założony przez niniejszego użytkownika
» 2013-11-11 13:26:38
Miałeś rację, pod tym względem nie sprawdzałem działania.
Dodałem jeszcze weryfikację, czy podane wartości są różne.
Czy teraz jest lepiej?
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

bool czyWylosowana( int liczba, int t[], int ile )
{
    if( ile <= 0 )
         return false;
   
    int licznik = 0;
    do
    {
        if( t[ licznik ] == liczba )
             return true;
       
        licznik++;
    } while( licznik < ile );
   
    return false;
}

bool czyPodana( int podana, int t[], int ile )
{
    if( ile <= 0 )
         return false;
   
    int licznik = 0;
    do
    {
        if( t[ licznik ] == podana )
             return true;
       
        licznik++;
    } while( licznik < ile );
   
    return false;
}


int wczytaj()
{
    int liczba;
    cin >> liczba;
    return liczba;
}

int losowanie( int liczby[ 3 ] )
{
    int wylosowana =( rand() % 3 ) + 0;
   
    return liczby[ wylosowana ];
}

int main()
{
    srand( time( 0 ) );
    int liczby[ 3 ];
    int wylosowane[ 2 ];
    int licznik = 0;
    int podana;
    int wartosc;
   
    cout << "podaj 3 rozne liczby" << endl;
    do
    {
        podana = wczytaj();
        if( czyPodana( podana, liczby, licznik ) == false )
        {
            liczby[ licznik ] = podana;
            licznik++;
        }
        else;
       
    } while( licznik < 3 );
   
    licznik = 0;
    do
    {
        int wartosc = losowanie( liczby );
        if( czyWylosowana( wartosc, wylosowane, licznik ) == false )
       
        {
            wylosowane[ licznik ] = wartosc;
            licznik++;
        }
    } while( licznik < 2 );
   
    licznik = 0;
    cout << "wylosowano: " << endl;
    do
    {
        cout << wylosowane[ licznik ] << endl;
        licznik++;
    } while( licznik < 2 );
   
   
    return 0;
}
P-96026
pekfos
» 2013-11-11 14:21:25
Czym się różnią czyWylosowana() i czyPodana()?
P-96029
xordi
» 2013-11-11 15:15:25
Nie wiem czy Ci to pomoże, ja to rozwiązałem w ten sposób (nie wiem czy dobrze zrobiłem - proszę o opinię):


(uwaga gotowe rozwiązanie)

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

bool czyJest( int losSpr, int tab[], int ileLiczbSpr )
{
    if( ileLiczbSpr <= 0 )
         return false;
   
    int i = 0;
    do
    {
        if( tab[ i ] == losSpr )
             return true;
       
        i++;
    } while( i < ileLiczbSpr );
   
    return false;
}

int wylosujLiczby( int t[], int ileLiczb, int pocz, int koniec ) {
    int i = 0;
    int los = 0;
    // int a = 0;
    int oPocz = koniec - pocz + 1;
    do {
        los =(( rand() % oPocz ) + pocz );
        if( czyJest( los, t, ileLiczb ) == false ) {
            t[ i ] = los;
            i++;
        }
    } while( i < ileLiczb );
   
    return 0;
}

int wpManual( int t[], int ileLiczb ) {
   
    int i = 0;
    int los = 0;
    do {
        std::cout << i + 1 << ".Podaj liczbe: ";
        std::cin >> los;
        if( czyJest( los, t, ileLiczb ) == false ) {
            t[ i ] = los;
            i++;
        } else {
            std::cout << "Powtorzyles liczbe: " << std::endl;
        }
    } while( i < ileLiczb );
   
    return 0;
}



int wypiszLiczby( int t[], int ileLiczb ) { //uzywane do debugowania
   
    int i = 0;
   
    do {
        std::cout << "tablica[" << i << "] = " << t[ i ] << std::endl;
        i++;
    } while( i < ileLiczb );
   
    return 0;
   
}

int main() {
    srand( time( NULL ) );
   
    int tablica[ 3 ]; //ilosc liczb usera
   
    int tymczasowa[ 2 ]; //ilosc liczb losowanych z liczb usera
   
    wpManual( tablica, 3 ); //liczby możemy wprowadzic recznie lub.....
    //wylosujLiczby(tablica, 3, 100, 300);              //dla leniwych mozna je wylosowac
   
    wylosujLiczby( tymczasowa, 2, 0, 2 ); //losowanie indeksow wylosowanych liczb usera
    //wypiszLiczby(tymczasowa, 2);                     //uzywane do debugowania
   
    int i = 0;
    std::cout << "Wylosowane liczby to: " << std::endl;
    do {
        std::cout << tablica[ tymczasowa[ i ] ] << std::endl; //wyswietlanie wylosowanych indeksow z tablicy usera
        i++;
    } while( i < 2 );
   
    return 0;
}

Stworzyłem tablicę pomocniczą i wylosowałem do niej 2 rekordy z liczb od 0 do 2, a potem użyłem tych rekordów jako indeks dla tablicy z liczbami podanymi przez usera.

(Na marginesie, sam dopiero zaczynam, ale gratuluję wszystkim doświadczonym spokoju i cierpliwości, sam dopiero zauważam jak ciężko się analizuje i sprawdza kod napisany przez kogoś innego. Dzięki Wam wszystkim :) )
P-96037
dawidrz
Temat założony przez niniejszego użytkownika
» 2013-11-11 16:53:13
Pekfos, oczywiście niczym się nie różnią. Usunąłem zbędną funkcję i podpiąłem obie weryfikacje pod pozostałą funkcję.
Xordi, dzięki za Twoją metodę:) w wolnej chwili przeanalizuję sobie Twój kod.
P-96048
« 1 »
  Strona 1 z 1