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

Lekcja 21 - zadanie domowe

Ostatnio zmodyfikowano 2017-02-18 23:24
Autor Wiadomość
e5500
Temat założony przez niniejszego użytkownika
Lekcja 21 - zadanie domowe
» 2017-02-18 14:42:29
Witam. W oparciu o zdobytą z tego kursu wiedzę próbuję napisać program z zadania domowego po lekcji 21. Niestety, z jakiegoś powodu, funkcja sprawdzająca, czy dana wartość z tablicy nie została już wylosowana stale zwraca true lub dzieje się po drodze coś innego, co powoduje, że program zapętla się wyświetlając komunikat "Wartosc powtorzona".

Tutaj mój kod:
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>

int losujIndeks()
{
    int indeks =( std::rand() % 8 ) + 0;
    return indeks;
}

bool czyWylosowana( int indeks, int tablicaI[] )
{
    int i = 0;
    do
    {
        if( indeks == tablicaI[ i ] )
             return true;
        else
             i++;
       
    } while( i <= 7 );
   
    return false; //brak w tablicy
}

int main()
{
    srand( time( NULL ) );
    int tablicaWartosci[ 7 ];
    int i = 0;
    do
    {
        std::cout << "Wprowadz wartosc nr " <<( i + 1 ) << ": ";
        std::cin >> tablicaWartosci[ i ];
        i++;
    } while( i <= 7 );
   
    int tablicaIndeksow[ 7 ];
    int indeks;
    i = 0;
   
    do
    {
        indeks = losujIndeks();
        if( czyWylosowana( indeks, tablicaIndeksow ) == false ) //if false
        {
            std::cout << "Wylosowano nr " << indeks << ": " << tablicaWartosci[ indeks ] << std::endl;
            tablicaIndeksow[ i ] = indeks;
            i++;
        }
        else //if true
        {
            std::cout << "Wartosc powtorzona" << std::endl;
        }
    } while( i <= 7 );
   
    return 0;
}
P-157939
maly7
» 2017-02-18 15:56:31
Funkcja działa dobrze, po prostu wychodzisz poza zakres tablicy.
Spójrz, tablica ma 7 elementów:
int tablicaIndeksow[ 7 ];

A mimo to, pętla
do...while
 wykonuje się nawet dla i == 7, czyli tablicaIndeksow[7].
} while( i <= 7 );
Jak wiadmo tablice są numerowane od 0, więc maksymalny element 7 elementowej tablicy to tablicaIndeksow[6].

Rozwiązanie:
Albo zwiększ tablice do rozmiaru 8, albo tam gdzie masz
while <= 7
 zamień na
while < 7
P-157946
mateczek
» 2017-02-18 19:14:30
prócz przekroczenia zakresów jest jeszcze problem z funkcją sprawdzającą. Problem polega na tym że funkcja sprawdza tablice z losowymi indexami. Rozwiązaniem może być funkcja sprawdzająca jak niżej !!! lub zaincjalizowanie tablicy indeksów wartościami które w normalnym losowaniu wystąpić nie mogą!!! np -1
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>

int losujIndeks()
{
    int indeks =( std::rand() % 7 ) + 0;
    return indeks;
}

bool czyWylosowana( int indeks, int tablicaI[], int size )
{
    for( int i = 0; i < size; i++ ) {
        if( indeks == tablicaI[ i ] ) return true;
       
    }
    return false; //brak w tablicy
}

int main()
{
    srand( time( NULL ) );
    int tablicaWartosci[ 7 ];
    int i = 0;
    do
    {
        std::cout << "Wprowadz wartosc nr " <<( i + 1 ) << ": ";
        std::cin >> tablicaWartosci[ i ];
        i++;
    } while( i < 7 );
   
    int tablicaIndeksow[ 7 ];
    int indeks;
    i = 0;
   
    do
    {
        indeks = losujIndeks();
        if( czyWylosowana( indeks, tablicaIndeksow, i ) == false ) //if false
        {
            std::cout << "Wylosowano nr " << indeks << ": " << tablicaWartosci[ indeks ] << std::endl;
            tablicaIndeksow[ i ] = indeks;
            i++;
        }
        else //if true
        {
            std::cout << "Wartosc powtorzona" << std::endl;
        }
    } while( i < 7 );
   
    return 0;
}
P-157974
e5500
Temat założony przez niniejszego użytkownika
» 2017-02-18 22:29:57
@maly7, dziękuję za twoją odpowiedź :)

@mateczek, czy możesz proszę wyjaśnić, w jaki sposób zapis for zamiast do while eliminuje możliwość wystąpienia wspomnianego przez ciebie zdarzenia? Podczas pisania programu przyszła mi do głowy taka możliwość, a nawet brałem ją pod uwagę przy szukaniu przyczyny występowania omawianego błędu. Jednakże nie rozumiem, w jaki sposób twoja funkcja czyWylosowana różni się od mojej.
P-157979
mateczek
» 2017-02-18 22:46:08
czy możesz proszę wyjaśnić, w jaki sposób zapis for zamiast do while eliminuje możliwość wystąpienia wspomnianego przez ciebie zdarzenia?

To nie "for" go eliminuje ale trzeci parametr wysyłany do funkcji, który sprawia, że przeszukujesz tylko ważną część tablicy. Użycie pętli For tylko skraca kod "możesz sobie przerobić na "while" nie  ma to najmniejszego znaczenia
P-157980
czaffik
» 2017-02-18 23:24:09
Można się zastanowić czemu w main działa ci dla i <= 7 a w funkcji już nie, wszystko przez i++ przez które w sprawdzaniu warunku wyjścia z pętli i uzyskuje wartość większą o 1, co w funkcji już za bardzo nie wychodzi a wszystko przez if-else gdzie w warunku może dojść do sprawdzenia elementu wychodzącego poza zakres tablicy. Użycie pętli for jest po chyba po prostu też pewniejsze.
P-157981
« 1 »
  Strona 1 z 1