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

question-closed Losowanie bez powtórzeń

0 głosów
1,149 wizyt
pytanie zadane 7 maja 2019 w C i C++ przez Woocashko Nowicjusz (150 p.)
zamknięte 7 maja 2019 przez Woocashko

Witam

Czy ktoś byłby chętny mi wytłumaczyć jaki błąd robię? Podsyłam kod niżej

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

using namespace std;

int main()
{
	srand(time(NULL));
	int tablica[6];
	int liczbaspr=0;

	for (int i = 0; i < 6; i++)
	{
		tablica[i] = rand() % 10 + 1;																				
	}

	for (int i = 0; i < 6; i++)
	{
		cout << tablica[i] << endl;
	}

	for (int i = 0; i < 6; i++)
	{
		liczbaspr = tablica[i];
		for (int z = 0; z < 6; z++)
		{
			if (liczbaspr == tablica[z+1])
			{
				tablica[z+1] = rand() % 10 + 1;
				z = 0;
				i = 0;
			}
		}
	}
	for (int i = 0; i < 6; i++)
	{
		cout << tablica[i] << endl;
	}

	system("pause");
}

Z góry dziękuje!

komentarz zamknięcia: Problem rozwiązany
1
komentarz 7 maja 2019 przez kalczur Gaduła (4,320 p.)
edycja 7 maja 2019 przez kalczur
porównujesz te same elementy bo druga pętla nie wyklucza elementu sprawdzanego i wychodzisz poza zakres tablicy z+1 czyli może być 6 a w masz indeksy tablicy od 0 do 5
komentarz 7 maja 2019 przez Woocashko Nowicjusz (150 p.)
No dobrze, ale jak dojdzie do tego tego 6 elementu tablicy, którego tak de-fakto nie ma to i tak warunek nie zostanie spełniony (chyba, że się mylę). Próbowałem także w tym if dodać warunek && (z+1) < 6, ale nic to nie zmieniało.
komentarz 7 maja 2019 przez kalczur Gaduła (4,320 p.)
no niby tak, zobacz moją odpowiedź. Jeśli nie rozumiesz którejś linijki to pisz

2 odpowiedzi

+1 głos
odpowiedź 7 maja 2019 przez kalczur Gaduła (4,320 p.)
wybrane 7 maja 2019 przez Woocashko
 
Najlepsza

Można zrobić to np. tak
 

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

using namespace std;

int main()
{
    srand(time(NULL));
    int tablica[6];

    for (int i = 0; i < 6; i++)
    {
        tablica[i] = rand() % 10 + 1;
    }

    for (int i = 0; i < 6; i++)
    {
        for (int z = 0; z < 6; z++)
        {
            if(z == i) z++;
            if (tablica[i] == tablica[z])
            {
                tablica[i] = rand() % 10 + 1;
                z = 0;
                i = 0;
            }
        }
    }

    for (int i = 0; i < 6; i++)
    {
        cout << tablica[i] << endl;
    }

    system("pause");
}

 

komentarz 7 maja 2019 przez Woocashko Nowicjusz (150 p.)
Wartości tablicy dalej się powtarzają. Z tego co sprawdzałem to najczęściej występuje błąd z pierwszą i ostatnią liczbą (na 10 prób, 6 razy pierwsza i ostatnia liczba była taka sama)
komentarz 7 maja 2019 przez kalczur Gaduła (4,320 p.)
poprawiłem
1
komentarz 7 maja 2019 przez Woocashko Nowicjusz (150 p.)
Twoja propozycja, którą napisałeś wcześniej była racją. Teraz wszystko działa. Bardzo dziękuje - zastanawiałem się nad tym od kilku dni, a problem leżał po prostu w moim złym rozumowaniu. Nie dość że wychodziłem poza tablice to jeszcze moje sprawdzanie w późniejszych etapach było wybiórcze (przy np 4 elemencie tablicy sprawdzałem 5 i 6, a nie wszystko, a mogło tam dojść do powtórzenia). Jeszcze raz dziękuje za cenną lekcje!
1
komentarz 7 maja 2019 przez DragonCoder Nałogowiec (36,500 p.)

Cenna lekcja bedzie jeszcze wywalenie srand z tego kodu i uzycie biblioteki: random .

0 głosów
odpowiedź 7 maja 2019 przez tangarr Mędrzec (155,120 p.)
Od razu po wylosowaniu nowej liczby powinieneś sprawdzić, czy nie ma jej w tablicy.
Powinieneś losować liczbę tablica[i] tak długo dopóki znajdujesz taką samą liczbę w zakresie [0, i-1].
komentarz 7 maja 2019 przez Woocashko Nowicjusz (150 p.)
#include <iostream>
#include <windows.h>
#include <time.h>

using namespace std;

int main()
{
	srand(time(NULL));
	int tablica[6];
	int liczbaspr=0;

	for (int i = 0; i < 6; i++)
	{
		liczbaspr = rand() % 7 + 1;
		for (int z = 0; z < 6; z++)
		{
			if (tablica[z] == liczbaspr)
			{
				liczbaspr = rand() % 7 + 1;
				z = 0;
			}
		}
		tablica[i] = liczbaspr;		
	}

	for (int i = 0; i < 6; i++)
	{
		cout << tablica[i] << endl;
	}


	system("pause");
}

Niestety, ale problem dalej występuje :(

 

komentarz 7 maja 2019 przez mrspock1 Mądrala (6,420 p.)
Ja zawsze tak robiłem że losowałem element porządkowy z zakresu indeksu tablicy. Wylosowany element był wartością tablicy dla tego indeksu (mógł być też typu znakowego). Następnie na miejsce wylosowane w tablicy dawałem wartość ostatniego jej elementu i zmniejszałem o jeden zakres tablicy. W ten sposób postępowałem dalej aż długość tablicy doszła do zera. Ciężko zastosować tą metodę gdy zakres indeksów losowania jest bardzo duży bo to zabiera dużo pamięci.
1
komentarz 7 maja 2019 przez tangarr Mędrzec (155,120 p.)

@Woocashko,

 

int main()
{
    srand(time(NULL));
    int tablica[6];
    int liczbaspr=0;

    // pierwszą liczbę inicjalizujemy poza petla
    tablica[0] = rand() % 7 + 1;

    for (int i = 1; i < 6; i++) {
        // powtarzamy losowanie az nie bedzie powtorzenia
        while(true) {
            liczbaspr = rand() % 7 + 1;

            for (int z = 0; z < i; z++) {
                // jezeli jest powtorzenie to losuj ponownie
                if (tablica[z] == liczbaspr)
                    continue;
            }
            // jezeli nie bylo powtorzen przerywamy petle
            break;
        }
        tablica[i] = liczbaspr;     
    }
 
    for (int i = 0; i < 6; i++)
    {
        cout << tablica[i] << endl;
    }
 
    system("pause");
}

 

komentarz 7 maja 2019 przez Woocashko Nowicjusz (150 p.)
@tangarr

Załóżmy

tablica[0] = 10; liczbaspr =10;

Dochodzimy do pierwszego sprawdzenia (gdzie i=1, z=0) i wychodzi nam, że liczby są takie same, należy powtórzyć pętle. Pętla się powtarza i "z" w naszym przypadku wynosi już 1. Jeśli przy ponownym losowaniu liczbaspr = 10 to nie wykonamy ponownego losowania, gdyż pętla "z" nie zostanie wykonana bo z < i (1<1) i dojdzie do zerwania pętli while co skutkuje wpisaniem liczbaspr do tablicy[1].

Program podaje liczby powtarzające się.
komentarz 8 maja 2019 przez tangarr Mędrzec (155,120 p.)

I tu mnie masz. Zupełnie zapomniałem o wewnętrznej pętli

 

int main()
{
    srand(time(NULL));
    int tablica[6];
    int liczbaspr=0;
 
    tablica[0] = rand() % 7 + 1;
 
    for (int i = 1; i < 6; i++) {
        bool retry = false;
        do {
            liczbaspr = rand() % 7 + 1;
 
            for (int z = 0; z < i; z++) {
                if (tablica[z] == liczbaspr) {
                    retry = true;
                    break;
                }
            }
        } while (retry)
        tablica[i] = liczbaspr;     
    }
  
    for (int i = 0; i < 6; i++) {
        cout << tablica[i] << endl;
    }  
    system("pause");
}

 

Podobne pytania

0 głosów
1 odpowiedź 567 wizyt
pytanie zadane 9 października 2018 w C i C++ przez Gadzic Nowicjusz (170 p.)
0 głosów
1 odpowiedź 13,098 wizyt
pytanie zadane 12 lipca 2018 w JavaScript przez demenator23 Nowicjusz (120 p.)
0 głosów
3 odpowiedzi 1,248 wizyt
pytanie zadane 28 czerwca 2018 w JavaScript przez Tomasz Ozi Orzech Początkujący (300 p.)

93,778 zapytań

142,736 odpowiedzi

323,388 komentarzy

63,382 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

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...