• 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ń

VPS Starter Arubacloud
0 głosów
428 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 (154,780 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 (154,780 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 (154,780 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ź 396 wizyt
pytanie zadane 9 października 2018 w C i C++ przez Gadzic Nowicjusz (170 p.)
0 głosów
1 odpowiedź 12,255 wizyt
pytanie zadane 12 lipca 2018 w JavaScript przez demenator23 Nowicjusz (120 p.)
0 głosów
3 odpowiedzi 769 wizyt
pytanie zadane 28 czerwca 2018 w JavaScript przez Tomasz Ozi Orzech Początkujący (300 p.)

92,452 zapytań

141,262 odpowiedzi

319,079 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...