Tablica gubi zadeklarowana wartosc po przejsciu jednorazowym petli, dlaczego?

0

Witam,

Mam taki oto problem z ktorym nie moge sobie poradzic i szczerze nie wiem co jest grane.


void Tablica::LosowanieLiczb() //Losowanie liczb JEDNORAZOWO zalezy od systemu
{
	nTablicaSystem = new int  [nLiczbaSystem]; 
	
	 // nLiczbaSystem jest zmienna wpisywana w momencie wywolania konstruktora (zakladamy 6)
	
	for (int i = 0; i < nLiczbaSystem; ++i)
	{
         nTablicaSystem[i] = 0; // wyzerowanie liczb tablicy
		
	}
	

	for (int i = 0; i < nLiczbaSystem; ) // losowanie 6 liczb od 1 do 49
	{
							
		nTablicaSystem[i] = rand() % 49 + 1;

		

		bool bPowtarzaSie = false;
		std::cout << i << std::endl; // wywolanie na ekranie aktualnie przebiegajacej wartosci petli I 

		_getch();
		
		for (int j = 0; j < i; ++j)
		{
			std::cout << nTablicaSystem[i] << " i " << i << std::endl; // wywolanie na ekranie aktualnie przebiegajacej wartosci petli I ; wartosc nTablicaSystem 'I' posiada jeszcze przydzielona losowo liczbe

			std::cout << nTablicaSystem[j] << " j " << j << std::endl; // wywolanie na ekranie aktualnie przebiegajacej wartosci petli I  ; wartosc nTablicaSystem 'J' posiada jeszcze przydzielona losowo liczbe
			_getch();
			if (nTablicaSystem[i] == nTablicaSystem[j]) // sprawdzenie czy sie powtarza
												
			{
			
			
			bPowtarzaSie = true;
			break;
			}		
			
			
					
		} // domyslam sie ze w tym momencie tablica gubi wpisana w aktualne oczko wartosc

		if (!bPowtarzaSie) ++i;

		std::cout << "Liczba " << i << " : ";
		std::cout << nTablicaSystem[i] << " , ";
		_getch();
	}
	
} 
		

Metoda losuje dowolne liczby z przedzialu i wpisuje do tablicy, jest to metoda klasy Tablica ktora wywoluje. Niestety po przejsciu jednego calego cyklu wartosc [i] np. 1 jest zero. Podane wywolania na ekranie sluza jedynie sprawdzeniu w ktorym momencie tablica gubi zadeklarowana wartosc. Nie wiem niestety dlaczego tak sie dzieje, ze po przejsciu raz petli nie zapisuje danych w tablicy, skoro wczesniej wszystko bylo ok. Zapomnialem dodac jeszcze jedna wazna rzecz, przy deklaracji tablicy 6 elementowej, 5 pierwszych elementow posiada wartosc 0, czasem piaty przybiera dobra wartosc(wylosowana), za to 6 ma wartosc ujemna czyli jest poza zakresem zawsze.

1

Pics or it didn't happen:

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

void losowanie(int n)
{
    int* tablica = new int[n];
    for (int i = 0; i < n;i++)
    {
        tablica[i] = rand() % 49 + 1;
        for (int j = 0; j < i; ++j)
        {
            if (tablica[i] == tablica[j])
            {
                i--;
                break;
            }
        }
    }

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

int main(){
  losowanie(49);
  return 0;
}

Poza tym wiesz że prościej byłoby użyć <set> który w czasie O(logn) sprawdza czy podany element już w nim istnieje?

0

Dziekuje za szybka odpowiedz, co sie tyczy kodu : dzieki za drobna optymalizacje (pozbycie sie wartosci logicznej) , kwestie int *nTablicaSystem zapisalem w naglowku jako deklaracje stad jej brak. Zmienilem inkrementacje na prawostronna i wszystko dziala. Nie specjalnie wiem dlaczego, bo przeciez w przypadku zmiennej I nie ma to znaczenia, wazne ze dodaje, a zmienna J jest od sprawdzania nastepnego elementu czy jest taki sam.
Co sie tyczy kodu set : przyjalem zasade ze bede pisal program na podstawie biezacej wiedzy i umiejetnosci a potem ewentualnie go optymalizowal w raz z poglebianiem wiedzy. Praktyka czyni mistrza :) swoja droga zajrzalem do biblioteki i dowiedzialem sie ze :

#include <set>

set<int> nTablica;

nTablica.insert = rand() 49 + 1; // dowiedzialem sie ze nie mozna wstawic dwoch takich samych elementow do zbioru ,to prawda ?
// nie wiem tylko jak okreslic ilosc elementow zbioru

set<int>::iterator it;

For(it=nTablica.begin(); it!=nTablica.end(); ++it)

Problem jest rowniez w tym ze ja w swoim programie operuje na tablicach. Mozna zamiast zbioru wstawic tablice? Czy potem musialbym przepisac do tablicy po losowaniu?

Ps. Pisane z komorki ,poprawie na komputerze. // Poprawione

1

Zbiór z matematycznego punktu widzenia nie zawiera elementów powtarzajacych się. Wrzucając drugi raz tą sama liczbę nic się po prostu nie stanie. Rozmiar <set> pobierasz metodą size(). Nawet jeśli potrzebujesz korzystać w innych miejscach z tablicy to szybciej będzie to przepisać bo masz O(nlogn) + O(n) zamiast O(n^2)

1

W przypadku 6-ciu elementów set będzie wolniejszy niż liniowo przeszukiwana tablica (chociażby z uwagi na fakt, że elementy set są alokowane na stercie). Złożoność to poniekąd O(1) gdyż ilość elementów jest z góry określona.

0

Dziękuję za wszystkie odpowiedzi, rozwiązały one problem i okazały się pomocne w przyszłości jak tylko będę wzbogacał swoją wiedzę C++.

Do zamknięcia.

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