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

Rozdział 17, funkcje, zadanie domowe

Ostatnio zmodyfikowano 2015-08-09 15:22
Autor Wiadomość
Eryk
Temat założony przez niniejszego użytkownika
Rozdział 17, funkcje, zadanie domowe
» 2015-08-07 22:23:00
Napisz funkcję, która losuje liczbę z przedziału od 50 do 60 włącznie. Wywołaj funkcję kilka razy (wypisz wylosowane wartości na ekran) w celu przetestowania czy działa ona poprawnie.

Proszę o sprawdzenie, ewentualną pomoc;
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int funkcja_losujaca()
{
    int a =( rand() % 11 ) + 50;
    return a;
}

int main()
{
    srand( time( NULL ) );
    cout << "Wylosowano...: " << funkcja_losujaca();
   
}

Napisz funkcję, która losuje liczbę z przedziału, który zostanie podany poprzez argumenty funkcji. Przetestuj funkcję w poniższy sposób:

C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
//... tu Twój kod
int main()
{
    srand( time( NULL ) );
    int start;
    std::cin >> start;
    int stop;
    std::cin >> stop;
    int ile = 20;
    do
    {
        std::cout << wylosuj( start, stop ) << std::endl;
        ile--;
    } while( ile > 0 );
   
    return 0;
}





I moja próba:


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

int wylosuj( int start, int stop )
{
    if( start > stop )
         return( rand() % stop ) + start;
   
}
int main()
{
    srand( time( NULL ) );
    int start;
    std::cin >> start;
    int stop;
    std::cin >> stop;
    int ile = 20;
    do
    {
        std::cout << wylosuj( start, stop ) << std::endl;
        ile--;
    } while( ile > 0 );
   
    return 0;
}
P-135858
carlosmay
» 2015-08-08 01:20:05
Pomylone zmienne. Start ze stop i źle wyliczony przedział losowanych liczb, (w ogóle nie wyliczone, przedział równy stop).
C/C++
int wylosuj( int start, int stop )
{
    if( start < stop )
         return( rand() %( stop - start + 1 ) ) + start; // stop - start + 1 daje przedział 11-tu liczb, czyli od start 10 do stop 20
    else
         return 0; // musi być drugi return gdy warunek nie jest spełniony
   
}
P-135863
Eryk
Temat założony przez niniejszego użytkownika
» 2015-08-08 17:45:51
Funkcja będzie - jak rozumiem - komunikowała się z drugą za pomocą argumentów. Ile będą wynosić, poda użytkownik. Po czym wykona się pętla, gdzie wyświetli się 20 liczb wylosowany za pomocą funkcji losującej srand. Jedyne co muszę ustalić to przedział tych liczb. Nie rozumiem jednak zapisu

( rand() %( stop - start + 1 ) ) + start


Mógłbyś wytłumaczyć?
P-135889
carlosmay
» 2015-08-08 18:38:47
C/C++
rand();
 funkcja losujaca liczbę z przedziału od 0 do RANDMAX (stała liczba).
C/C++
( rand() % a ) + b; // a to jest przedział liczb, natomiast b to jest liczba początkowa,
// % to modulo (reszta z dzielenia)

To co napisałem:
stop - start + 1 => a;
start => b;

Jeśli losujesz liczby od 10 d0 20 włącznie musisz to wyliczyć, czyli stop(20) - start(10) + 1 - bo przedział od 10 do 20 zawiera 11 liczb.
Liczba a jest dodawana do reszty z dzielenia modulo, dzięki temu uzyskujesz żądany przedział.

Edit: dobrze od samego początku stosować wyliczanie wartości zamiast stałych wartości, ponieważ w razie zmiany np. zakresu
zmieniasz zmienną w jednym miejscu a reszta sama się wylicza (kod jest bardziej uniwersalny).
P-135890
Eryk
Temat założony przez niniejszego użytkownika
» 2015-08-08 20:50:44
Wydaje mi się, że rozumiem. Tylko dlaczego taki zapis jest niepoprawny?

C/C++
if( start > stop )
{
    return rand() %( start - stop + 1 ) + stop;
}
P-135898
carlosmay
» 2015-08-09 00:33:02
Warunek działa poprawnie, lecz wyklucza zadziałanie rand() gdy zmienna start będzie mniejsza od stop,
jeśli start będzie większy do stop wyliczony przedział będzie miał wartość ujemną. (lipa)

Reasumując: prawidłowe dane nie działa, niepoprawne dane działa błędnie. (zadziała tylko liczby jakie wylosuje będą inne niż się spodziewasz).
Napisz krótki program losujący i podaj mu raz większy start od stop, raz mniejszy i zobacz co będzie.

I jeszcze jedno: zabezpiecz się przed uruchomieniem rand() gdy przedział będzie wynosił 0, bo będzie awaria.
P-135902
Witicar
» 2015-08-09 01:30:12
Na kursie użyto formułki
rand() % zakres + poczatek
teraz przyjrzyjmy się temu co napisał kolega wyzej
rand() %( stop - start + 1 ) + start
wezmy dla przykładu zakres liczb od 10 do 20, mamy tutaj do czynienia z 11 liczbami (10,11,12,13,14,15,16,17,18,19,20) a jezeli zastosujemy sie do formulki to
zakres=(stop-start+1) czyli 20-10+1 daje nam 11. Dlatego dodajemy "1" bo odjelismy o 1 za duzo gdyz poza zakresem znajduje sie 9 liczb (1,2,3,4,5,6,7,8,9) a w zapisie zostalo odjete 10, wiec trzeba to skorygować.
Także jak kolega napisał oraz było to umieszczone w kursie w operacjach matematycznych, zabezpiecz swoj program przed przypadkiem gdzie "zmienna%0", gdyz reszta z dzielenia czegos przez zero nie istnieje (nie dzieli sie przez zero) czyli u nas "stop-start+1" nie moze wynosic zero. Jak to zrobic powinienes wiedzieć, takze jezeli nie potrzebujesz ujemnego zakresu mozesz zrobić coś aby stop>=start, wtedy masz gwarancje losowania liczb dodatnich.
P-135904
Eryk
Temat założony przez niniejszego użytkownika
» 2015-08-09 14:03:27
Napisałem dwa programy. W pierwszym od liczby większej odejmowana jest mniejsza.

C/C++
int wylosuj( int start, int stop )
{
    if( start > stop )
         return rand() %( start - stop + 1 ) + stop;
   
    else if( start < stop )
         return rand() %( stop - start + 1 ) + start;
   
}

W drugim zaś zwraca zero, jeżeli start jest mniejszy od stop.


C/C++
int wylosuj( int start, int stop )
{
    if( start > stop )
         return rand() %( start - stop + 1 ) + stop;
   
    else if( start < stop )
         return 0;
   
}

Mogę uznać zadanie za wykonane? Pierwsze jak rozumiem też?
P-135921
« 1 » 2
  Strona 1 z 2 Następna strona