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

Poziom 2- Temat 21. Losowanie bez powtórzeń. Błąd w losowaniu wartości.

Ostatnio zmodyfikowano 2014-01-18 13:27
Autor Wiadomość
Jaskola
Temat założony przez niniejszego użytkownika
Poziom 2- Temat 21. Losowanie bez powtórzeń. Błąd w losowaniu wartości.
» 2014-01-16 22:41:47
Witam. Byłbym wdzięczny jeśli ktoś pokazałby mi gdzie w moim programie tkwi błąd :). Otóż program prawidłowo wczytuje bez powtórzeń liczby, lecz kiedy przychodzi pora na wylosowanie ośmiu z nich wypisuje jedną 8 razy. Oto kod
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
int zapisz()
{
    int liczba;
    int i = 0;
    do
    {
        std::cin.clear();
        std::cin.sync();
        std::cin >> liczba;
        if( std::cin.good() == 1 )
        {
            std::cout << "Ok." << std::endl;
            return liczba;
            i++;
        }
        else
             std::cout << "Blad!" << std::endl;
       
    } while( i == 0 );
   
}
int losuj()
{
    srand( time( 0 ) );
    return( rand() % 10 ) + 1;
}
bool powtorzenie( int liczba, int tab[], int j )
{
    int i = 0;
    if( j <= 0 )
         return false;
   
    do
    {
        if( tab[ i ] == liczba )
             return true;
       
        i++;
    } while( i < j );
   
    return false;
   
}
int wypisz( int tab[] )
{
    int i = 0;
    std::cout << "Wylosowane liczby: " << std::endl;
    do
    {
        std::cout << tab[ i ] << std::endl;
        i++;
    } while( i < 8 );
   
}
int main()
{
    srand( time( 0 ) );
    int podana;
    int liczba = 10;
    int liczba2 = 8;
    int spis[ liczba ];
    int wylosowane[ liczba2 ];
    int i = 0;
    int j = 0;
    std::cout << "Podaj 10 liczb" << std::endl;
    do
    {
        podana = zapisz();
        if( powtorzenie( podana, spis, i ) == false )
        {
            spis[ i ] = podana;
            ++i;
        } else std::cout << "Liczba zostala juz podana" << std::endl;
       
    } while( i < liczba );
   
    do
    {
        int losowana = spis[ losuj() ];
        if( powtorzenie( losowana, wylosowane, j ) == false )
        {
            int k = spis[ losowana ];
            wylosowane[ j ] = k;
            j++;
        }
    } while( j < liczba2 );
   
    wypisz( wylosowane );
}
Nie wiem czy to błąd w rozumowaniu ,czy po prostu coś gdzieś wpisałem nie na to miejsce :D. Proszę o pomoc :).
P-102341
Chlorek
» 2014-01-16 22:56:48
Nie czytałem całego kodu, wiec jak masz jeszcze gdzieś błędy to nie wiem.
Ale odnośnie typowo twojego pytania:
W funkcji int losuj() za każdym razem ustawiasz "ziarno" funkcją srand(). A że program wykonuje się dość szybko to w przeciągu paru milisekund (nie wszystkie systemy update'ują czas co 1ms, niektóre robią to np. co 10ms) sprawia, że masz ten sam seed. Po prostu srand() wywołaj tylko raz na samym początku programu.
P-102344
alixir
» 2014-01-17 07:15:34
Tak jak poprzednik napisał wywal:
srand( time( 0 ) );
 z funkcji losuj.
Dodatkowo losujesz błędny zakres liczb (od 1 do 10) wychodząc poza zakres tablicy
return( rand() % 10 ) + 1;
 Usuń +1 z końca.
Masz jeszcze kilka kosmetycznych błędów typu:
  • funkcja Wypisz powinna być typu void a nie int (jeśli nie zwracasz nic)
  • funkcja zapisz w przypadku wystąpienia błędu nie zwraca wartości - a powinna
  • funkcja main nie zwraca wartości - a powinna
P-102345
Jaskola
Temat założony przez niniejszego użytkownika
» 2014-01-17 18:34:38
Wielkie dzięki :). Poprawiłem błędy które podaliście, dodałem zmienną przechowującą wartość funkcji losuj() i wszystko bangla.
P-102381
pekfos
» 2014-01-17 18:37:12
Masz jeszcze kilka kosmetycznych błędów typu:
  • funkcja Wypisz powinna być typu void a nie int (jeśli nie zwracasz nic)
  • funkcja zapisz w przypadku wystąpienia błędu nie zwraca wartości - a powinna
  • funkcja main nie zwraca wartości - a powinna
Pierwsze 2 to poważne błędy, a nie kosmetyczne. Trzeci to nie błąd.
P-102382
PCS
» 2014-01-18 13:03:04
Czołem, nie chcę zakładać nowego wątku, mam tylko jedno pytanko odnośnie tej lekcji, nie zadania domowego. Mam problem z interpretacją tej lini kodu.

if( czyBylaWylosowana( liczba, wylosowane, wylosowanych ) == false )
      Dlaczego akurat false. Dzięki za odpowiedź z góry.
Chodzi dokładnie o tę lekcje:
http://cpp0x.pl/kursy/Kurs-C++/Poziom-2/Losowanie-bez-powtorzen/293
P-102434
leon_w
» 2014-01-18 13:21:35
W tym przypadku funkcja czyBylaWylosowana(liczba,wylosowane,wylosowanych) zwraca "true", gdy liczba już była wylosowana, albo "false" gdy nie była wylosowana.
Czyli jeżeli funkcja czyBylaWylosowana() zwróci "false", zostaną wykonane instrukcje zawarte w klamrach (lub jedna instrukcja bezpośrednio pod "if", jeśli nie użyto klamer)za operatorem "if". Jeżeli funkcja zwróci "true", instrukcje nie zostaną wykonane.
P-102436
PCS
» 2014-01-18 13:27:51
Dzięki wielkie za objaśnienie, od razu mi się to rozświetliło.
P-102438
« 1 »
  Strona 1 z 1