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

Losowanie liczb z tablicy bez powtórzeń

Ostatnio zmodyfikowano 2016-09-03 14:00
Autor Wiadomość
gregwoow
Temat założony przez niniejszego użytkownika
Losowanie liczb z tablicy bez powtórzeń
» 2016-08-18 01:57:03
Cześć, rozwiązuje zadanie z kursu c++

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.

http://cpp0x.pl/kursy/Kurs-C++/Poziom-2/Losowanie-bez-powtorzen/293
 
Od razu powiem że program w zasadzie działa, ale męczę się z nim IIgi dzień bo działa, no prawie, o ile losuje 2 liczby z 3 w tablicy, o tyle narzędzie do zapobiegania powtarzania się wyników nie działa, a nie wiem zupełnie dlaczego, jak dla mnie powinna choć dopiero zaczynam naukę... Testuję potem program wpisując wartości 1,2,3, większość czasu wylosuje dwie nie powtarzając, ale czasem wylosuje np 1,1


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

int podaj_liczby( int igb[] )
{
    cout << "Podaj 3 liczby " << endl; // To jest mało ważne
    int a = 0;
    do
    {
        cin >> igb[ a ];
        a++;
    } while( a < 3 );
   
}

bool franc( int p, int rr[] ) // Funckcja losująca
{
    if( p <= 0 );
   
    return false;
   
    int i = 0;
    do
    {
        if( rr[ i ] == rr[ p ] ); // w tym wypadku losujemy tylko 2 liczby więc jezeli 1sza == 2ga to powinno zwócić true            
       
        return true;
        i++;
    } while( i > p );
   
    return false;
}


int main()
{
    srand( time( NULL ) );
   
    int p = 0;
    int d = 3;
    int liczby[ 3 ];
    podaj_liczby( liczby );
    int rr[ 2 ];
    cout << "Wylosowane liczby" << endl;
    do
    { rr[ p ] =( rand() % d );
       
        if( franc( p, rr ) == false )
             cout << liczby[ rr[ p ] ] << endl;
       
        p++;
       
    } while( p < 2 );
   
   
    return 0;
}
P-150961
gregwoow
Temat założony przez niniejszego użytkownika
Pozmieniałem
» 2016-08-18 05:03:59
Zwiększyłem pulę losowanych liczb, troszeczkę zmodyfikowałem poprzedni kod (zamienienie inta na void w funckji 'podaj_liczby' okazało się sporo zmienić) i zmodyfikowałem pętlę dodając na jej końcu elsa, który wyświetli " ! " na ekranie w razie niespełnienia warunku if. A dodałem bo dostrzegłem, że zwyczajnie warunek if musiał ZAWSZE zwracać wartośc faulse choć nie powinien, teraz po modyfikacjach widać na ekranie aplikacji w którym momencie warunek przyjął wartość true i wypluł '!'. Teraz się dopiero zrobiło dziwnie, bo program czasami uznaje że liczby się powtórzyły (co widzę dzięki ! przed liczbą) a czasami ma to gdzieś i losuje te liczby z powtarzaniem...

Kod wstawię tu dla czytelności wpisu:

http://wklej.org/id/2785012/.
P-150964
carlosmay
» 2016-08-18 06:20:29
Śledzenie programu, krok po kroku debuggerem rozjaśni działanie kodu.
Zerknij
P-150965
gregwoow
Temat założony przez niniejszego użytkownika
Ehh dobra mam!
» 2016-09-01 01:32:27
Przysiadłem do tego po dłuższej przerwie i znalazłem, głupi błąd, w linii 28, było: while (i > p); int i było ustawione na zero więc nic dziwnego że funkcja ciągle zwracała pożądany fałsz, skoro pętla od razu się kończyła, parametr p == 0 wcześniej i tak zwracał fałsz, a jak inkrementował do wartości 1 to while (0 > 1) jest fałszem i kończy działanie pętli, nawet biorąc pod uwagę fakt że chwilę przed parametr i też się inkrementuje to wciąż while (1 > 1) jest flauszem i kończy pętlę, wystarczyło zmienić ten znak na: while (i < p)

Taki szczegół a tak namieszał. tu macie kod
http://wklej.org/id/2811425/.
Albo też tu:

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

void podaj_liczby( int igb[] )
{
    cout << "Podaj 10 liczb " << endl;
    int a = 0;
    do
    {
        cin >> igb[ a ];
        a++;
    } while( a < 10 );
   
}

bool franc( int p, int rr, int bgc[] )
{
    if( p == 0 )
         return false;
   
    int i = 0;
    do
    {
        if( bgc[ i ] == rr )
             return true;
       
        i++;
    } while( i < p );
   
    return false;
}


int main()
{
    srand( time( NULL ) );
    int p = 0;
    int d = 8;
    int liczby[ 10 ];
    podaj_liczby( liczby );
    int rr;
    int bgc[ 8 ];
    cout << "Wylosowane liczby" << endl;
    do
    { rr =( rand() % d );
       
        if( franc( p, rr, bgc ) == false )
        {
           
            cout << liczby[ rr ] << endl;
            bgc[ p ] = rr;
            p++;
        }
        else
             cout << " ! ";
       
    } while( p < 8 );
   
   
    return 0;
}

A tak btw, można prosić o jakiś link do tego jak korzystać z debbugera? Bo w sumie nie mam pojęcia :)
P-151287
carlosmay
» 2016-09-01 02:19:52
A tak btw, można prosić o jakiś link do tego jak korzystać z debbugera? Bo w sumie nie mam pojęcia :)
No to pochwal się na czym tam pracujesz.

edit: Przydałaby się legenda opisująca zmienne ;)
P-151288
gregwoow
Temat założony przez niniejszego użytkownika
» 2016-09-01 17:12:07
Polecam zacząć czytanie od Maina!

A używam code::blocks 10.05 ;)

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

void podaj_liczby( int liczby[] )
{
    cout << "Podaj 10 liczb " << endl;
    int a = 0;
    do
    {
        cin >> liczby[ a ];
        a++;
    } while( a < 10 );
   
}

bool losowanie( int p, int rr, int bgc[] )
{
    if( p == 0 ) /*p na początku ma wartość 0, jako że pierwsza wylosowana liczba na pewno z niczym sie nie powtórzy dałem ten zapis, aby funcja od razu
        zwróciła fausz */
         return false;
   
    int i = 0;
    do
    {
        if( bgc[ i ] == rr ) /* porównuję obecny wynik losowania z ktorymś z poprzednich, jeżeli już taki wcześniej został wylosowany, funkcja zwróci true
                i warunek if w mainie nie zostanie spełniony*/
             return true;
       
        i++;
    } while( i < p );
   
    return false;
}


int main()
{
    srand( time( NULL ) );
    int p = 0; // ta zmienna będzie potrzebna i opinana w pętli do - while
   
    int d = 8; // ta zmienna jest tu w sumie zbędna, chodzi o podzielenie przez nią randa i w ten sposób uzyskanie losowania liczb od 0 do 7
   
    int liczby[ 10 ]; /*to jest tablica do której zapisując się wprowadzone w funckji podaj_liczby wartości wprowadzone przez
        urzytkownika*/
   
    podaj_liczby( liczby );
    int rr; // ta zmienna jest tylko po to, by przypisywać do niej wynik dzielenia z resztą, a potem ten wynik przypisać do któregoś elementu tablicy bgc
   
    int bgc[ 8 ]; /* Ta tablica jest dosyć ważna, po tym jak wylosuję liczbę od 0 do 7 i dopiszę ją do zmiennej rr, to musze jakoś zapamiętać
        co już wylosowałem a czego nie, więc przypisuje wartości wylosowane odpowiednim elementom tej tablicy*/
   
   
    cout << "Wylosowane liczby" << endl;
    do
    { rr =( rand() % d ); //tu odbywa się losowanie
       
        if( losowanie( p, rr, bgc ) == false )
        {
           
            cout << liczby[ rr ] << endl; /*jeżeli funkcja losowanie zwróci false to wyświetlam jedną z liczb wcześniej podanych przez urzytkownika
                        działa to tak że jak wynikiem losowanie będzie liczba 1, to zmienna rr przyjmie wartość 1, więc efektywnie wyświetlę liczba[1]*/
           
            bgc[ p ] = rr; // przypisuję wylosowaną liczbę od 0 do 7, do któregoś elementu tablicy bgc, zmienna p definiuje do którego
            p++;
        }
    } while( p < 8 );
   
   
    return 0;
}
P-151301
karambaHZP
» 2016-09-01 17:30:05
http://wiki.codeblocks.org​/index.php​/Debugging_with_Code::Blocks


Polecam zacząć czytanie od Maina!
@carlosmay ma rację. Nazwy nic nie mówią, a kod czyta się tragicznie.
Przy długim kodzie i nie opisowych zmiennych mnóstwo czasu traci się na
zrozumieniu co robi kod. Swojego czasu nie musisz szanować, ale szanuj czas innych.
Nikt tutaj nie jest twoim osobistym pachołkiem, więc takie uwagi nie są na miejscu.
P-151302
gregwoow
Temat założony przez niniejszego użytkownika
» 2016-09-03 14:00:23
@karambaHZP Dzięki za link do debuga, co do czytelności kodu myślę że masz rację, powinienem na to zwracać uwagę.
P-151387
« 1 »
  Strona 1 z 1