• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wypełnienie tablicy losowymi liczbami

Object Storage Arubacloud
0 głosów
28,569 wizyt
pytanie zadane 3 grudnia 2017 w C i C++ przez SzaaBao Początkujący (380 p.)

Cześć!

Mam za zadanie wypełnić tablicę losowymi liczbami. Próbuję, próbuję i średnio wychodzi. Czy da się wypełnić tablicę n elementową liczbami losowymi? Czy tablica jednak musi mieć podaną wielkość? Dodam że zakres liczb losowych musi być zainicjowany podczas uruchomienia programu. Napisałem takie oto 2 kody jednakże nie są one chyba poprawne. Pomożecie? Chodzi o tablice jednowymiarowe.

1.

#include <iostream>
#include <cstdlib>
#include <time.h>

using namespace std;

int n;
int liczba;
int main()
{
    int tab[n];
    cout<<"Podaj zakres"<<endl;
    cin>>n;
    srand(time(NULL));
    for(int i=0; i<n; i++)
    {
        for(int i=0; i<n; i++)
        {
           tab[i]=rand()%n+1;
        }
    }





    return 0;
}

2.

#include <iostream>
#include <cstdlib>
#include <time.h>

using namespace std;

int n;
int liczba;
int main()
{
    int tab[100];
    cout<<"Podaj zakres"<<endl;
    cin>>n;
    srand(time(NULL));
    for(int i=0; i<n; i++)
    {
        tab[100]=rand()%n+1;
    }


    return 0;
}

 

komentarz 3 grudnia 2017 przez SzaaBao Początkujący (380 p.)
Ta int liczba nie jest potrzebna, zapomniałem usunąć :D
komentarz 3 grudnia 2017 przez SzaaBao Początkujący (380 p.)


#include <iostream>
#include <cstdlib>
#include <time.h>
 
using namespace std;
 
int n;
int liczba;
int main()
{
    int tab[n];
    cout<<"Podaj zakres"<<endl;
    cin>>liczba;
    srand(time(NULL));
    for(int i=0; i<n; i++)
    {
        tab[i]=rand()%liczba+1;
    }
 
 
 
 
 
    return 0;
}

czy to jest ok?

3 odpowiedzi

0 głosów
odpowiedź 3 grudnia 2017 przez criss Mędrzec (172,590 p.)
    int tab[n];
    cout<<"Podaj zakres"<<endl;
    cin>>n;

Skąd wy bierzecie te dziwne konstrukcje. Najpierw tworzysz tablice, a potem określasz jej rozmiar? Sensu niewiele, prawda? Poza tym: rozmiar tablicy musi być stałą znaną w czasie kompilacji. Tak, GCC ci pozwala na takie coś, ale generalnie powinieneś tego unikać bo na innym ci się nie skompiluje. W C to jest ok, ale widzę, że piszesz w C++.

Pomijając powyższe:
Pierwszy kod: dlaczego podwójna pętla? n razy nadpisujesz każdy element i... liczby są tak samo losowe jakby były przy jednym przejściu.
Drugi kod: lepiej, ale wszystko przypisujesz do indeksu 100, co już nie ma sensu szczególnie gdy największy indeks to 99. Poza tym: co gdy user poda liczbę >100? 

komentarz 3 grudnia 2017 przez SzaaBao Początkujący (380 p.)
dzieki za rade
0 głosów
odpowiedź 3 grudnia 2017 przez k222 Nałogowiec (30,150 p.)

No dobra to weźmy ten 1 program i idziemy po kolei:

int n = 100;
int tab[n];

int tab[100];

Jeżeli rozmiar tablicy ma być zawsze taki sam to te dwa sposoby są jak najbardziej ok, czy n będzie przed int main czy w środku w tym przykładzie nie robi różnicy (poczytaj sobie - zmienna globalna vs zmienna lokalna) tylko do n musisz przypisać jakąś wartość, bo w twoim programie masz to bez wartości i program nie wie ile to jest n, ten drugi spsób też jest ok, ale ponieważ n przyda się dalej to ten pierwszy sposób deklarowania wydaje mi się być lepszy. 

cout<<"Podaj zakres"<<endl;
cin>>n;

skoro n jest rozmiarem tablicy, to nie może być jednocześnie zakresem - od tego pewnie miała być zmienna liczba

cout<<"Podaj zakres"<<endl;
    cin>>liczba;
for(int i=0; i<n; i++)
    {
        for(int i=0; i<n; i++)
        {
           tab[i]=rand()%n+1;
        }
    }

funkcja raand już zwraca losowe wartości (pseudolosowe - tutaj też znajdziesz w google różnice pomiędzy losowymi a pseudolosowymi) i nie musisz dodatkowo kombinować z n i drugim for'em bo to tylko czas zajmuje a poza tym zakresem miała być liczba więc pewnie miało być

for(int i=0; i<n; i++)
    {
           tab[i]=rand() % liczba + 1;

    }

i jak to poprawisz to powinno działać

komentarz 3 grudnia 2017 przez SzaaBao Początkujący (380 p.)
dzieeeki
komentarz 3 grudnia 2017 przez SzaaBao Początkujący (380 p.)
#include <iostream>
#include <cstdlib>
#include <time.h>

using namespace std;

int n;
int liczba;
int main()
{
    int tab[n];
    cout<<"Podaj zakres"<<endl;
    cin>>liczba;
    srand(time(NULL));
    for(int i=0; i<n; i++)
    {
        tab[i]=rand()%liczba+1;
    }





    return 0;
}

Teraz jest niby okej. Prosze potwierdź czy to jest dobrze.

komentarz 3 grudnia 2017 przez k222 Nałogowiec (30,150 p.)

nie

 

for(int i=0; i<n; i++)
    {
    cout<<tab[i]<<"  ";
    if(i % 10 == 0) cout<<endl;
    }

 

wklej to w 20 wiersz - prosta pętla wypisująca po kolei liczby z tablicy a potem się zastanów dlaczego nic nie wypisało, 

następnie możesz się zastanowić ile liczb powinno wypisać

komentarz 3 grudnia 2017 przez SzaaBao Początkujący (380 p.)
#include <iostream>
#include <cstdlib>
#include <time.h>

using namespace std;

int n=100;
int liczba;
int main()
{
    int tab[n];
    cout<<"Podaj zakres"<<endl;
    cin>>liczba;
    srand(time(NULL));
    for(int i=0; i<n; i++)
    {
        tab[i]=rand()%liczba+1;
    }
    for(int i=0; i<n; i++)

    return 0;

}

Teraz jest ok. Wypisuje mi 100 losowych liczb z zadanego przedziału.

 

komentarz 3 grudnia 2017 przez SzaaBao Początkujący (380 p.)
Oczywiście bez tego fora na końcu :D. Nie usunął się.
0 głosów
odpowiedź 3 grudnia 2017 przez mokrowski Mędrzec (155,460 p.)
edycja 3 grudnia 2017 przez mokrowski

No tak.. od czego tu zacząć żeby było krótko.. oj chyba nie będzie :-/

  1. Dodaj do swojego kompilatora przełączniki ostrzeżeń. Dla gcc i podobnych (gcc, clang) to będzie na Twoim etapie nauki -Wall -Wextra -pedantic  
  2. Załóżmy że chcesz użyć zmiennych globalnych co w ogólnym podejściu jest złą praktyką. Jeśli jednak chcesz to zrobić, proszę hermetyzuj je z użyciem static co spowoduje że nie będą widoczne poza 1 jednostką kompilacji.
  3. Jeśli stosujesz nagłówek <time.h> z C w przypadku C++, należy użyć <ctime>. To dobre przyzwyczajenie bo w danym środowisku taki nagłówek jest odpowiednio przygotowany do użycia.
  4. Zmienna n, jeśli chcesz ją użyć w kontekście wielkości tablicy, powinna być stała. Dla języka C++11 i nowszych możesz użyć constexpr . Jeśli jednak nie chcesz/nie możesz, wystarczy const.
  5. Używanie "using namespace std", jest ogólnie złą praktyką. Lepiej wpisywać nazwę przestrzeni nazewniczej przy danej funkcji. To jest dobry zwyczaj i warto trenować jego użycie :-)
  6. Zmienne indeksów dla tablic (wszelkie wielkości kontenerów), lepiej deklarować jako size_t. Ten typ zmiennej jest do tego przeznaczony.
  7. Nie nadużywaj std::endl. Oprócz wyświetlenia znaku nowej linii, wymusza on czyszczenie bufora strumienia. To jest czasochłonne zadanie i powinno mieć uzasadnienie.
  8. main() w C++ nie wymaga zwracania 0 (zera). Ma tak tylko ta funkcja. Sama zwróci zero.
  9. Przyzwyczajaj się do używania pre(inkrementacji/dekrementacji). W większości przypadków będzie ona szybsza.
  10. Przy inicjalizacji generatora liczb losowych, zachodzi konieczność rzutowania time(NULL) do typu unsigned int.

Po takich zmianach, nieco "hiper-poprawny" kod będzie wyglądał tak:

#include <iostream>
#include <cstdlib>
#include <ctime>

static const size_t n = 100;
static int liczba;

int main()
{
    int tab[n];
    std::cout << "Podaj zakres: ";
    std::cin >> liczba;

    srand(static_cast<unsigned int>(time(NULL)));

    for(size_t i = 0; i < n; ++i)
    {
        tab[i] = rand() % liczba + 1;
    }
    // Prezentacja danych
    for(size_t i = 0; i < n; ++i)
    {
        std::cout << tab[i] << ' ';
    }
    std::cout << '\n';
}

Co do języka C++ w wersji 2003, można zakończyć... Dalej były by to już poprawki w kierunku i nowszych standardów jak i lepszych technik programowania... 

Ok, jak forum pozwala, jadę dalej :-)

  1. Od standardu C++11, lepiej zamiast rand() odziedziczonego jeszcze z C, użyć nagłówka <random> z dedykowanym "osprzętem do generowania liczb losowych".
  2. Należy wydzielić funkcje które ma wykonywać program.
  3. Zakładając że upierasz się przy tablicach (niech będzie), warto napisać funkcję która sama wydedukuje jakiej wielkości jest tablica.
  4. Jeśli (jak samo polecenie wskazuje) masz wygenerować liczby losowe, warto użyć std::generate() z <algorithm>

Wtedy wyglądało by to tak:

#include <algorithm>
#include <random>
#include <iostream>

static constexpr size_t n = 100;

template<size_t N>
void table_generate(int (&table)[N], int range)
{
    std::random_device rd;
    std::mt19937_64 gen(rd());
    std::uniform_int_distribution<> dis(0, range);
    std::generate(table, table + N, [&]{ return dis(gen);});
}

template<size_t N>
void table_show(int (&table)[N])
{
    for(const auto& val: table)
    {
        std::cout << val << ' ';
    }
    std::cout << '\n';
}

int main() {
    int table[n];
    int range;
    std::cout << "Podaj zakres: ";
    std::cin >> range;
    table_generate(table, range);
    table_show(table);
}

 

komentarz 4 grudnia 2017 przez SzaaBao Początkujący (380 p.)

Dziękuję za rady. Przestudiuję je i postaram się stosować. Tylko widzisz... Chodzę do 2 klasy LO. Jest to mój pierwszy rok rozszerzenia i o praktycznie żadnej z tych rzeczy o której pisałeś nauczyciel nam nie wspominał (np. nadużywaniu endl;).  Z tą biblioteką time.h to nawet nam dzisiaj powtarzał żeby ją wpisywać. Tak czy siak jeszcze raz dziękuję za poświęcony czas. Postaram się wyrobić dobre nawyki wink.

Podobne pytania

+2 głosów
3 odpowiedzi 3,197 wizyt
pytanie zadane 12 listopada 2019 w C i C++ przez Tawka Nowicjusz (200 p.)
0 głosów
1 odpowiedź 1,216 wizyt
pytanie zadane 9 stycznia 2018 w C i C++ przez Tomek112 Początkujący (310 p.)
0 głosów
2 odpowiedzi 3,280 wizyt

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...