Losowanie bez powtórzeń

0

Witam,
Mógłbym prosić o nakierowanie mnie na to gdzie jest błąd.

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

int main ()
{
    srand (time (NULL));

    int aTablica[5];
    int wylosowana =(rand ()% 10) + 1;
    int nLicznik = 0;
    do
    {
        if (aTablica[nLicznik] == wylosowana)
        return true;

        aTablica[ nLicznik ] = wylosowana;
        nLicznik++;

    }while (nLicznik < 5);

    nLicznik = 0;
    do
    {
     cout << "Liczba nr." << nLicznik << " = " << aTablica[nLicznik] << endl;
     nLicznik++;

    }while (nLicznik < 5);

    return 0;
}
 
0

Nie analizowałem kodu, ale to:

        if (aTablica[nLicznik] == wylosowana)
        return true;

Zamknie cały program jeżeli warunek się spełni.


Ogólnie ten kod cały jest bezsensu; a w każdym razie to 'losowanie' liczb :|
0

Ale co ty chcesz osiagnac mi powiedz?

Tworzysz tablice wypelniona zapewne domyslnie przez kompilator zerami
Losuje jakas liczbe z zakresu 1-10
Potem w ogole z wnetrza petli w mainie robisz return jesli element tablicy(ktory na 100% jest rozny) jest rowny wylosowanej liczbie.
W innym wypadku czyli praktycznie zawsze wypelniasz tablice(cala!) 1 wylosowana liczba.

Co ty konkretnie chcesz tu zrobic? Jak wylosowac bez powtorzen, to musisz losowac w petli nowa liczbe i sprawdzac czy na pozycjach od 0 do n-1, gdzie n jest aktualna pozycja do zapisania nowej liczby nie ma juz takie samej.

0

Tak więc uczę się programowania a ten program jest po prostu przykładem jak to działa losowanie liczb bez powtórzeń.

0
int i = 1; // do wypelniania tabeli wylosowanym liczbami
    int tab[5],losuj=rand()%10+1,n=0; // n do sprawdzania czy sie nie powtarza
    tab[0] = rand() % 10 + 1; // losujesz 1 na starcie bo nie powtorzy sie z innym ;p
    do
    {
        while(n<i) // ten while sluzy do sprawdzania czy sie nie powtarza
        {
            if(tab[n]==losuj) // jesli na danej pozycji sie powtarza to losujemy i porownujemy od nowa
            {
                losuj = rand()%10+1;
                n = 0;
            }
            else n++; // w innym wypadku lecimy dalej
        }
        tab[i] = losuj; // po znalezieniu takiej liczby ktora sie nie powtarza mozemy ja wpisac
        i++; // i lecimy dalej
    }while(i<5);
0

Zależnie od tego, co chcesz wylosować istnieją prostsze metody. Jeżeli chcesz losować z liczb całkowitych i zbiór możliwych wartości nie jest duży, szybciej i prościej jest stworzyć tablicę z możliwymi liczbami a następnie ją poprzestawiać losowo i wybrać tyle elementów, ile się potrzebuje.
Jeżeli zbiór jest bardzo duży albo mają to być liczby rzeczywiste, można posłużyć się std::set. Ten kontener gwarantuje nam, że znajdą się w nim tylko unikalne liczby, trzeba więc losować tak długo, aż liczba jego elementów będzie odpowiednia. (W przypadku liczb rzeczywistych trzeba wziąć pod uwagę co oznacza dla nas "taka sama liczba")

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
 
int main() {
  std::srand(std::time(NULL));
 
  int available_numbers[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
  std::random_shuffle(available_numbers, available_numbers + 10);
 
  for (size_t i = 0; i < 5; ++i) {
    std::cout << available_numbers[i] << ' ';
  }     
 
  return 0;
}

http://ideone.com/Tl258

We wszystkich tych przypadkach trzeba pamiętać, że losowanie za pomocą rand() i modulo jest proste, ale bardzo niedobre.

0

#include <set>

srand(time(NULL)) ;
int array[5] ;
std::set<int> isExist ;
for(int i=0; i<5; ++i) 
{
    int tmp ;
    do
    {
        tmp = rand()%10+1 ;
    } while(isExist.find(tmp) != isExist.end()) ;
    isExist.push_back(tmp) ;
    array[i] = tmp ;
}    
0

up: co to za dziwny pomysł? std::set sam sprawdza, czy liczba jest, czy jej nie ma.

#include <iostream>
#include <set>
#include <ctime>
#include <cstdlib>
#include <algorithm>
#include <iterator>
 
int main() {
  std::srand(std::time(NULL));
 
  std::set<int> numbers;
 
  while (numbers.size() < 5) {
    numbers.insert((std::rand() % 10) + 1);
  }
 
  std::copy(numbers.begin(), numbers.end(), std::ostream_iterator<int>(std::cout, " "));
        
  return 0;
}

http://ideone.com/OygTR

Na końcu można po prostu zastąpić std::ostream_iterator dowolnym kontenerem, do którego się to zmieści. Poza tym kontenery z biblioteki standardowej mają konstruktory, które wykorzystują iteratory.

0

A moze by tak samemu, a nie polegac na magicznych objektach. Magicznych, czyli -nie wiem jak, ale dziala.
Kiedy elementarny kod bedzie nawet bardziej zwiezly.
Inzynierowie od klockow lego.

1 użytkowników online, w tym zalogowanych: 0, gości: 1