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

Zadanie rodział 21

Ostatnio zmodyfikowano 2011-07-09 10:59
Autor Wiadomość
M4vo
Temat założony przez niniejszego użytkownika
Zadanie rodział 21
» 2011-07-09 07:46:14
Witam mam problem z zadaniem:
"1. Napisz program, który wczyta 3 liczby podane przez użytkownika do tablicy, a następnie wylosuje 2 z nich bez powtórzeń. Wynik wypisz na ekran. Postaraj się napisać ten program w oparciu o funkcje."

Dość długo próbowałem sam rozwiązać te zadanie, ale niestety bez większych rezulatów.
Mój kod:
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>

void wpisz( int tablica[] )
{
    int a;
    a = 0;
    do
    {
        std::cout << "\nPodaj " << a << " liczbe:" << std::endl;
        std::cin >> tablica[ a ];
        a++;
    } while( a != 3 );
   
}

int losowanie( int tablica[] )
{
    int a =( rand() % 3 );
    int x = tablica[ a ];
    return x;
}

bool test( int liczba, int tablica[], int miejsce )
{
    int l = 0;
    do
    {
        if( tablica[ l ] == liczba )
        {
            return true;
        }
        l++;
    } while( l != miejsce );
   
    return false;
}

bool test2( int liczba, int tablica2[], int miejsce )
{
    int l = 0;
    do
    {
        if( tablica2[ l ] == liczba )
        {
            return false;
        }
        else
        {
            l++;
        }
       
    } while( l < miejsce );
   
    return true;
}

void wypisz( int tablica[], int tablica2[] )
{
    int a, b;
    a = 0;
    b = 0;
    do
    {
        std::cout << "\nPozycja " << a << "w tabeli 1 to: " << tablica[ a ] << std::endl;
        a++;
    } while( a != 3 );
   
    do
    {
        std::cout << "\nPozycja " << b << "w tabeli 1 to: " << tablica2[ b ] << std::endl;
    } while( b != 2 );
   
}

int main()
{
    int tablica[ 3 ];
    int tablica2[ 2 ];
    int l;
    srand( time( NULL ) );
    wpisz( tablica );
    int a = 0;
    do
    {
        int liczba = losowanie( tablica );
        tablica2[ a ] = liczba;
        if( test( liczba, tablica, 3 ) == true && test2( liczba, tablica2, a ) == true )
             a++;
       
    } while( a < 2 );
   
    wypisz( tablica, tablica2 );
    return 0;
}

Może ktoś będzie wiedział co zrobiłem źle.
P-35596
m4tx
» 2011-07-09 08:44:53
Więc tak:
Namieszałeś coś nieźle przy tym kodzie, bo po wybraniu tych 3 liczb zjada mi procesor.
Nie używasz w ogóle pętli for(..), a powinieneś. Przykład:
C/C++
bool test2( int liczba, int tablica2[], int miejsce )
{
    int l = 0;
    do
    {
        if( tablica2[ l ] == liczba )
        {
            return false;
        }
        else
        {
            l++;
        }
       
    } while( l < miejsce );
   
    return true;
}
Możesz to bez problemu zamienić na:
C/C++
bool test2( int liczba, int tablica2[], int miejsce )
{
    for( int l = 0; l < miejsce; l++ )
    if( tablica2[ l ] == liczba )
         return false;
   
    return true;
}

Prawda, że krócej? :)
Zauważyłeś też zapewne, że nie ma nawiasów klamrowych. Są one w tym przypadku bowiem niepotrzebne. Jeżeli
if(..)
 lub pętla
do..while
,
while(..)
, czy
for(..)
 nie znajdzie nawiasu klamrowego, wykonuje kod do znalezienia pierwszego średnika.

Przy ifach nie musisz pisać == true, np tutaj:
if( test( liczba, tablica, 3 ) == true && test2( liczba, tablica2, a ) == true )
Wystarczy coś takiego:
if( test( liczba, tablica, 3 ) && test2( liczba, tablica2, a ) )

Postaraj się to napisać z wykorzystaniem pętli for(..) i jakichś komentarzy.

(btw., jakiś dziwny ten kurs... Najpierw losowanie bez powtórzeń, a potem pętla for(..)?! Hm, ciekawie, więc najpierw coś trudniejszego, a potem podstawy... hah!)
P-35597
M4vo
Temat założony przez niniejszego użytkownika
» 2011-07-09 09:00:17
Dzięki za odpowiedz. Możliwe ze w kodzie troche namieszałem bo zacząłem go wczoraj dosc późno poprawiać. Co do pętli for to wg. ad. autora kursu:"Uwaga!
Treść niniejszego rozdziału nie zawiera rozwiązania problemu lecz wskazówki - zadanie wymaga przede wszystkim zastanowienia się i przeprowadzenia szczegółowej analizy problemu do konkretnego przypadku przedstawionego w zadaniu. Zadanie nie wymaga większej wiedzy z zakresu programowania niż ta, która została przedstawiona do tej pory. "
Pętla for jest w rodziale 22, więc staram się wykonać to zadanie bazując na wiedzy zdobytej w rozdziałach 1-21.
P-35599
m4tx
» 2011-07-09 09:13:18
Zadanie to rzeczywiście nie wymaga większej wiedzy niż w rozdziałach 1-21, jednak pętla for(..) jest w tym zadaniu takim ułatwieniem i sposobem na skrócenie kodu, że powinna się znaleźć w rozdziałach 1-21. Tym bardziej, że to podstawa w języku C++.
Postaraj się więc opanować pętlę for(..). Proponuję napisać też to zadanie domowe od nowa, bez pośpiechu, dokładnie analizując każdą linijkę kodu. Napisanie kodu od nowa często jest dobrym sposobem na wiele błędów. Pośpiech w programowaniu natomiast prowadzi do niczego. Jeżeli wciąż będziesz miał problemy, napisz jeszcze raz na forum, postaramy się pomóc :)
P-35600
M4vo
Temat założony przez niniejszego użytkownika
» 2011-07-09 10:09:46
Coś ruszyła gdy zacząłem pisać od nowa z komentarzami. Pisanie komentarzy pozwala jeszcze raz zastanowaic sie nad kazda funckją ponownie, dzieki czemu poprwaiłem kilka błędów. Teraz program losuje liczby, tylko z powtórzeniami. Analizowalem kod i moim zdaniem wszystko powinno działać i losowac bez powtórzeń, ale tak nie jest..

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


void wpisz( int tablica1[] ) //Funkcja wprowadza wpisane przez użytkownika liczby do tablicy
{
    int l = 0;
    do
    {
        std::cout << "\nPodaj " << l << " pozycje: " << std::endl;
        std::cin >> tablica1[ l ];
        l++;
    } while( l != 3 );
   
}

int losuj( int tablica1[] ) //Funkcja losuje
{
    int a = rand() % 3; //losowanie cyfry z zakresu 0-2
    int b = tablica1[ a ]; //zmienna przyjmuje wartosc liczby z tablicy o pozycji 0-2, tablica zawiera liczby wprowadzone przez uzytkownika
    return b; //zwrot przypisanej liczby z tablicy
}


bool spr2( int liczba, int tablica2[], int miejsce ) //funkcja sprawdza czy wylosowana liczba nie powtarza sie z poprzednio wylosowana
{
    int l = 0;
    if( miejsce <= 0 ) //jesli pozycja tabeli jest = 0 jets to pierwsza losowana liczba, wiec nie moze sie powtarzac
         return true;
    else
    {
        do
        {
            if( liczba == tablica2[ l ] ) //jesli wylosowana liczba znajduje sie w tabeli liczb wylosowanych funkcja zwraca false
                 return false;
           
            l++; //jesli nie przechodzi do kolejnej pozycji tabeli
        } while( l != miejsce );
       
        return true; //po wyjscu z petli zwaraca true
    }
    //return true;
}

void podaj( int tablica1[], int tablica2[] ) //funckja wyswietla wprowadzone i wylosowane liczby
{
    std::cout << "\n" << tablica1[ 0 ] << " " << tablica1[ 1 ] << " " << tablica1[ 2 ] << std::endl;
    std::cout << "\n" << tablica2[ 2 ] << " " << tablica2[ 1 ] << std::endl;
}

int main()
{
    srand( time( NULL ) );
    int tablica1[ 3 ]; //tablica trzymajaca liczby wprowadzone przez uzytkownika
    int tablica2[ 2 ]; //tablica trzymajaca wylosowane liczby
    wpisz( tablica1 );
    int l = 0;
    do
    {
        int liczba = losuj( tablica1 ); //przypisanie zmiennej liczba wylosowanej liczby z zakresu liczb podanych przez uzytkownika
        tablica2[ l ] = liczba; //wpisanie w tablicy w pozycji l wylosowanej liczby
        if( spr2( liczba, tablica2, l ) ) //jesli dostjemy z funkcji true przechodzimy dalej
             l++;
       
    } while( l != 2 );
   
    podaj( tablica1, tablica2 );
    return 0;
}
P-35603
m4tx
» 2011-07-09 10:55:40
Pobawiłem się trochę debuggerem, co pomogło w znalezieniu błędu :) Ale o tym zaraz.
Więc tak:
Komentarze bardzo ułatwiły mi rozwiązanie tego, jednak takie komentarze typu "jesli dostjemy z funkcji true przechodzimy dalej" nie są potrzebne, bo to od razu widać. Ale np. "tablica trzymajaca liczby wprowadzone przez uzytkownika" - to się okazało bardzo pomocne.
W funckji spr2() masz
if( miejsce <= 0 )
. Ja to zamieniłem na
if( miejsce == 0 )
, bo i tak nigdy miejsce nie będzie mniejsze od 0.

Ale błąd nie jest funkcji spr2(), ale... podaj() :)
Masz tam bowiem:
std::cout << "\n" << tablica2[ 2 ] << " " << tablica2[ 1 ] << std::endl;
Co jest ogromnym błędem, ponieważ
tablica2[ 2 ]
 W ogóle nie istnieje. Miejsca w tablicy liczy się od ZERA!
Tak więc poprawny kod wygląda następująco:
std::cout << "\n" << tablica2[ 1 ] << " " << tablica2[ 0 ] << std::endl;

Pozdrawiam
P-35607
M4vo
Temat założony przez niniejszego użytkownika
» 2011-07-09 10:59:45
Dzięki bardzo, sam bym na to nie wpadł. Błąd wziąl się stąd ze gdy pierwszy raz pisałem te linie odruchowo wrzucałem{} w tablicach zamiast [], potem gdy poprawialem błędy kopiowałem wpisy z linii dla tablicy 1, widocznie zapomniałem zmienic pozycji...

Edit:

Dla potomnych również mających problem z tym zadaniem zamieszczam kody do obu zadań tego rozdziału z komentarzami:

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


void wpisz( int tablica1[] ) //Funkcja wprowadza wpisane przez użytkownika liczby do tablicy
{
    int l = 0;
    do
    {
        std::cout << "\nPodaj " << l << " pozycje: " << std::endl;
        std::cin >> tablica1[ l ];
        l++;
    } while( l != 3 );
   
}

int losuj( int tablica1[] ) //Funkcja losuje
{
    int a = rand() % 3; //losowanie cyfry z zakresu 0-2
    int b = tablica1[ a ]; //zmienna przyjmuje wartosc liczby z tablicy o pozycji 0-2, tablica zawiera liczby wprowadzone przez uzytkownika
    return b; //zwrot przypisanej liczby z tablicy
}

bool spr2( int liczba, int tablica2[], int miejsce ) //funkcja sprawdza czy wylosowana liczba nie powtarza sie z poprzednio wylosowana
{
   
    if( miejsce <= 0 ) //jesli pozycja tabeli jest = 0 jets to pierwsza losowana liczba, wiec nie moze sie powtarzac
         return true;
    else
    {
        int l = 0;
        do
        {
            if( liczba == tablica2[ l ] ) //jesli wylosowana liczba znajduje sie w tabeli liczb wylosowanych funkcja zwraca false
            { return false; }
            l++; //jesli nie przechodzi do kolejnej pozycji tabeli
        } while( l != miejsce );
       
        return true; //po wyjscu z petli zwaraca true
    }
    //return true;
}

void podaj( int tablica1[], int tablica2[] ) //funckja wyswietla wprowadzone i wylosowane liczby
{
    std::cout << "\n" << tablica1[ 0 ] << " " << tablica1[ 1 ] << " " << tablica1[ 2 ] << std::endl;
    std::cout << "\n" << tablica2[ 0 ] << " " << tablica2[ 1 ] << std::endl;
}

int main()
{
    srand( time( NULL ) );
    int tablica1[ 3 ]; //tablica trzymajaca liczby wprowadzone przez uzytkownika
    int tablica2[ 2 ]; //tablica trzymajaca wylosowane liczby
    wpisz( tablica1 );
    int l = 0;
    do
    {
        int liczba = losuj( tablica1 ); //przypisanie zmiennej liczba wylosowanej liczby z zakresu liczb podanych przez uzytkownika
        tablica2[ l ] = liczba; //wpisanie w tablicy w pozycji l wylosowanej liczby
        if( spr2( liczba, tablica2, l ) == true )
        { l++; }
    } while( l != 2 );
   
    podaj( tablica1, tablica2 );
    return 0;
}

ad.2

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


void wpisz( int tablica1[] ) //Funkcja wprowadza wpisane przez użytkownika liczby do tablicy
{
    int l = 0;
    do
    {
        std::cout << "\nPodaj " << l << " pozycje: " << std::endl;
        std::cin >> tablica1[ l ];
        l++;
    } while( l != 10 );
   
}

int losuj( int tablica1[] ) //Funkcja losuje
{
    int a = rand() % 10; //losowanie cyfry z zakresu 0-9
    int b = tablica1[ a ]; //zmienna przyjmuje wartosc liczby z tablicy o pozycji 0-9, tablica zawiera liczby wprowadzone przez uzytkownika
    return b; //zwrot przypisanej liczby z tablicy
}

bool spr2( int liczba, int tablica2[], int miejsce ) //funkcja sprawdza czy wylosowana liczba nie powtarza sie z poprzednio wylosowana
{
   
    if( miejsce < == 0 ) //jesli pozycja tabeli jest = 0 jest to pierwsza losowana liczba, wiec nie moze sie powtarzac
         return true;
    else
    {
        int l = 0;
        do
        {
            if( liczba == tablica2[ l ] ) //jesli wylosowana liczba znajduje sie w tabeli liczb wylosowanych funkcja zwraca false
            { return false; }
            l++; //jesli nie przechodzi do kolejnej pozycji tabeli
        } while( l != miejsce );
       
        return true; //po wyjscu z petli zwaraca true
    }
   
}

void podaj( int tablica1[], int tablica2[] ) //funckja wyswietla wprowadzone i wylosowane liczby
{
    int a = 0;
    int b = 0;
    do
    {
        std::cout << " " << tablica1[ a ] << " ";
        a++;
    } while( a != 10 );
   
    std::cout << "\n";
    do
    {
        std::cout << " " << tablica2[ b ] << " ";
        b++;
    } while( b != 8 );
   
}

int main()
{
    srand( time( NULL ) );
    int tablica1[ 10 ]; //tablica trzymajaca liczby wprowadzone przez uzytkownika
    int tablica2[ 8 ]; //tablica trzymajaca wylosowane liczby
    wpisz( tablica1 );
    int l = 0;
    do
    {
        int liczba = losuj( tablica1 ); //przypisanie zmiennej liczba wylosowanej liczby z zakresu liczb podanych przez uzytkownika
        tablica2[ l ] = liczba; //wpisanie w tablicy w pozycji l wylosowanej liczby
        if( spr2( liczba, tablica2, l ) == true )
        { l++; }
    } while( l != 8 );
   
    podaj( tablica1, tablica2 );
    return 0;
}
P-35608
« 1 »
  Strona 1 z 1