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

Losowanie bez powtórzeń

0 głosów
768 wizyt
pytanie zadane 14 stycznia 2018 w C i C++ przez Maciej3206 Użytkownik (570 p.)

Witam, 

zadaniem kodu jest losowanie liczb bez powtórzeń. Wielkość zbioru oraz ilość liczb deklarowana jest przez użytkownika. Pierwsza liczba jest poza zbiorem i nie potrafię znaleźć przyczyny tego błędu.

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

using namespace std;

int main()
{
    srand (time(NULL));
    int wielkosc_zbioru, ilosc_cyfr, licznik_losowan=0;

    cout << "Podaj wielkosc zbioru losowania: ";
    cin>>wielkosc_zbioru;
    cout<<endl<<"Losowanie odbedzie sie ze zbioru liczb od 1 do "<<wielkosc_zbioru<<endl;
    cout<<"Podaj ilosc losowanych cyfr: ";
    cin>>ilosc_cyfr;
    cout<<endl;
    int *tabl;
    tabl=new int [ilosc_cyfr];

    for(int i=1;i<=ilosc_cyfr;i++)
    {
        int liczba=rand()%wielkosc_zbioru;
        for (int j=1;j<=i;j++)
        {
            if (liczba==tabl[j])
            {
                i=-1;
            }
            else
            {
                tabl[i]=liczba;
            }
        }
    }
    for(int i=1;i<=ilosc_cyfr;i++)
    {
        cout<<tabl[i]<<endl;
    }
   getchar();
}

2 odpowiedzi

+1 głos
odpowiedź 14 stycznia 2018 przez j23 Mędrzec (195,220 p.)

Pierwszy błąd: indeksujesz od 1 do ilosc_cyfr. W C/C++ indeksuje się od zera. Indeksowanie wartością równą wielkości tablicy to błąd - wychodzisz poza dozwolony zakres.

Drugi: linia 29. Pewny jesteś tego -1? Następny obrót pętli (22) będzie dla i = 0, a Ty indeksujesz przecież od 1.

Trzeci: cyfra to nie liczba :P Cyfra to symbol graficzny.

0 głosów
odpowiedź 14 stycznia 2018 przez niezalogowany
edycja 14 stycznia 2018

Tablice są numerowane od 0, a nie od 1. Musisz więc pozmieniać każdą pętlę. W pętli sprawdzającej powtórzenia powinieneś i cofać tylko o 1, a nie na wartość -1. Poza tym wygodniej byłoby Ci zapisać wylosowaną liczbę od razu do tablicy. Dodaj jeszcze jakieś ograniczenie gdy zakres jest za mały w stosunku do ograniczonych liczb (przykładowe wejście 3 5):

#include <iostream>
#include <cstdio>
#include <ctime>
#include <windows.h>

using namespace std;

int main()
{
	srand(time(NULL));
	int wielkosc_zbioru, ilosc_cyfr, licznik_losowan = 0;

	cout << "Podaj wielkosc zbioru losowania: ";
	cin >> wielkosc_zbioru;
	cout << endl << "Losowanie odbedzie sie ze zbioru liczb od 1 do " << wielkosc_zbioru << endl;
	cout << "Podaj ilosc losowanych cyfr: ";
	cin >> ilosc_cyfr;
	cout << endl;
	int *tabl = new int[ilosc_cyfr];

	for (int i = 0; i < ilosc_cyfr; i++)
	{
		tabl[i] = rand() % wielkosc_zbioru;
		for (int j = 0; j < i; j++) // j < i, bo inaczej poniższy if nigdy się nie wykona
		{
			if (tabl[i] == tabl[j])
			{
				i--;
				break; // gdy zostanie znalezione powtórzenie przerwij pętlę 'j'
			}
		}
	}
	for (int i = 0; i < ilosc_cyfr; i++)
	{
		cout << tabl[i] << endl;
	}
	getchar();
}
komentarz 14 stycznia 2018 przez #fff Nowicjusz (140 p.)
Polecam sprawdzić kod przed jego wysłaniem ;)
komentarz 14 stycznia 2018 przez niezalogowany
O dzięki za info już poprawione ;)

Podobne pytania

0 głosów
1 odpowiedź 570 wizyt
pytanie zadane 9 października 2018 w C i C++ przez Gadzic Nowicjusz (170 p.)
0 głosów
2 odpowiedzi 10,174 wizyt
pytanie zadane 5 września 2017 w C i C++ przez Adampio Początkujący (310 p.)
0 głosów
3 odpowiedzi 1,258 wizyt
pytanie zadane 28 czerwca 2018 w JavaScript przez Tomasz Ozi Orzech Początkujący (300 p.)

93,788 zapytań

142,753 odpowiedzi

323,429 komentarzy

63,393 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.

...