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

Losowanie bez powtórzeń rozdz.21 - dlaczego losuje liczbę z poza zakresu .

Ostatnio zmodyfikowano 2011-06-01 12:06
Autor Wiadomość
mykosik
Temat założony przez niniejszego użytkownika
Losowanie bez powtórzeń rozdz.21 - dlaczego losuje liczbę z poza zakresu .
» 2011-05-31 23:44:10
Witam i proszę o wyjaśnienie .Dlaczego gdy usunę klamry w pętli po  if( czyBylaWylosowana( liczba, wylosowane, wylosowanych ) == false ) wylosuje mi jedna liczbę z poza zakresu np:2359128?
Jakie znaczenie maja tu klamry.Przepraszam ,że kod jest nie kolorowy , ale nie wiem jak to zrobić- proszę przy okazji o info.


C/C++
int main()
{
    srand( time( 0 ) );
    int wylosowane[ 5 ];
    int wylosowanych = 0;
    do
    {
        int liczba = wylosuj();
        if( czyBylaWylosowana( liczba, wylosowane, wylosowanych ) == false )
        {
            wylosowane[ wylosowanych ] = liczba;
            wylosowanych++;
        } //if
    } while( wylosowanych < 5 );
   
    wylosowanych = 0;
    do
    {
        std::cout << wylosowane[ wylosowanych ] << std::endl;
        wylosowanych++;
    } while( wylosowanych < 5 );
   
    return 0;
}
P-33714
malan
» 2011-06-01 00:12:42
1. Kolorowanie składni: » KursyKurs STC kurs => » Kurs STC » Kolorowanie składniKolorowanie składni języka C++ lekcja
2. Jeżeli usuniesz klamry to w tym przypadku, kiedy warunek będzie spełniony (czyli funkcja
czyBylaWylosowana
 zwróci
false
) wykona się tylko instrukcja:
wylosowane[ wylosowanych ] = liczba;
, a index tablicy (
wylosowanych
) będzie wzrastał z każdym obiegiem pętli. Kiedy warunek się nie wykona to do tablicy nie wpisujesz nic, więc ta liczba (2359128) to zapewne śmieć, który pozostał w pamięci.
Przykładowo:
wylosowanych = 0;

[Krok 1]
liczba = 5;
czyBylaWylosowana returned false
wylosowane[0] = 5;
wylosowanych = 1;

[Krok 2]
liczba = 10;
liczyBylaWylosowana returned false
wylosowane[1] = 10;
wylosowanych = 2;

[Krok 3]
liczba = 5;
liczyBylaWylosowana returned true
wylosowanych = 3;

//...
Widzisz co się dzieje w kroku trzecim, kiedy program wylosuje tą samą liczbę?
P-33716
mykosik
Temat założony przez niniejszego użytkownika
» 2011-06-01 01:15:26
Rozumiem, czyli w przypadku istnienia klamer licznik zwiększy swoja wartość prawidłowo(wg oczekiwania programu) TYLKO pod warunkiem kiedy funkcja zwróci wartość false.Kiedy ich nie będzie to licznik też zwiększy swoją wartość ale nieprawidłowo bo policzy wystąpienie wartości true wypisując liczbę jako  tzw śmieci.
Bardzo dziękuję  za rzetelne wyjaśnienie i pozdrawiam.
P-33717
malan
» 2011-06-01 01:52:12
Co do tych klamer to poczytaj jeszcze o tym w kursie: » Kurs C++ » Poziom 1Instrukcja warunkowa if ... else lekcja (Instrukcja lub blok instrukcji).
Kiedy ich nie będzie to licznik też zwiększy swoją wartość ale nieprawidłowo bo policzy wystąpienie wartości true(...)
To się zgadza, ale kiedy warunek się nie wykona, to do tablicy nic nie zostanie wpisane. Te śmieci tam są od momentu kiedy zmienna (w Twoim przypadku tablica) zaczyna istnieć- nie trzeba ich specjalnie wpisywać ;)
Sam zobacz:
C/C++
int main()
{
    srand( time( 0 ) );
    int wylosowane[ 5 ];
    int wylosowanych = 0;
   
    for( int i = 0; i < 5; ++i )
    {
        std::cout << "wylosowane[" << i << "] = " << wylosowane[ i ] << std::endl;
    }
   
    //...
P-33718
mykosik
Temat założony przez niniejszego użytkownika
» 2011-06-01 10:29:54
Dziekuję , teraz wszystko jasne w tym temacie ale rodzi się następny problem.
Otóż kiedy np zwiększę rozmiar tablicy wylosowanych do 11 -wylosowane[ 11 ] to przy
( rand() % 10 ) + 1 program się skompiluje ale nic nie wykona.
Dzieje się to zawsze kiedy liczba elementów tablicy jest większa od od liczby stop w( rand() % stop ) + start
Dlaczego tak się dzieje.Bardzo proszęe o wskazówkę.
P-33720
DejaVu
» 2011-06-01 10:42:28
Szanowny Pan moderator malan prosił wielmożnego jaśnie Pana o zapoznanie się z kursem STC i wyedytowaniem pierwszego posta tak aby składnia była kolorowa :) Cieszymy się, że rozwiązany został Twój pierwszy problem, niemniej jednak również prosimy abyś zadbał o wygląd swoich postów, bowiem ktoś kiedyś będzie miał podobny problem i fajnie będzie, jeżeli treść będzie wyglądała względnie schludnie :) Co do Twojego nowego problemu - bez kodu nie pomożemy :) Zwiększenie tylko i wyłącznie rozmiaru tablicy nie ma prawa wpłynąć na zachowanie programu, a Ty to właśnie sugerujesz.
P-33721
mykosik
Temat założony przez niniejszego użytkownika
» 2011-06-01 11:17:10
Bardzo przepraszam i już się poprawiam otóż gdy jest:
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>

bool czyBylaWylosowana( int iLiczba, int tab[], int ile )
{
    if( ile <= 0 )
         return false;
   
    int i = 0;
    do
    {
        if( tab[ i ] == iLiczba )
             return true;
       
        i++;
    } while( i < ile );
   
    return false;
}

int wylosuj()
{
    return( rand() % 10 ) + 1; // przy wartości 10 zmieniłem wylosowane[5] na wylosowane [11]
}

int main()
{
    srand( time( 0 ) );
    int wylosowane[ 11 ]; //zmieniłem z 5 na 11
    int wylosowanych = 0;
    do
    {
        int liczba = wylosuj();
        if( czyBylaWylosowana( liczba, wylosowane, wylosowanych ) == false )
       
        {
           
            wylosowane[ wylosowanych ] = liczba;
            wylosowanych++;
        } //if
    } while( wylosowanych < 11 ); //z 5 na 11
   
    wylosowanych = 0;
    do
    {
        std::cout << wylosowane[ wylosowanych ] << std::endl;
        wylosowanych++;
    } while( wylosowanych < 11 ); //z 5 na 11
   
   
   
    return 0;
}



Program skompiluje się , w logu kompilacji jest 0 błędów i 0 ostrzeżeń.W oknie programu nie ma nic tylko prompt.
P-33722
DejaVu
» 2011-06-01 11:34:08
No to tak: wyobraź sobie, że losujesz bez powtórzeń 3 liczby ze zbioru 2 elementowego: X, Y.
Pierwszy krok: wylosowało Y; pozostało X (i jeszcze dwie do wylosowania)
Drugi krok: wylosowało X; pozostało nic (i jeszcze jedna do wylosowania)
Trzeci krok: czegokolwiek nie wylosujesz i tak się powtórzy, więc algorytm się zapętla.
P-33723
« 1 » 2
  Strona 1 z 2 Następna strona