Problem z programem: Tablice/wskaźniki, przekazywanie dancyh.

0

Cześć wszystkim.
Mam tablicę dynamiczną której rozmiar ustala użytkownik, a elementy są generowane losowo z przedzialu, powiedzmy, 1-100. Następnie z tej tablicy chciałbym wybrać elementy z przedziału (srednia - odchylenie, srednia + odchylenie) i wpisac je do nowej tablicy. Sęk w tym że za każdym razem rozmiar nowej tablicy będzie inny i nie wiem jak go określić. Nie wiem też czy dobrze przekazuje dane z pierwszej tablicy do drugiej bo te wskaźniki dla mnie to jakaś czarna magia. Poniżej funkcja tworzenia drugiej tablicy.

//wyznacza przedzial, tworzy nowa tablice
int*przedzial(int*tab, int n, float sre, float odch)
{
	float left = sre - odch; //lewa granica przedzialu
	float right = sre + odch; //prawa granica przedzialu
	//int count = 0;
	int *tab2 = new int[n];
	int wsk = 0;
	
	{
		for (int i = 0; i < n; i++)
			tab2[n] = 0;

	}
	for (int i = 0; i < n; i++)
	{
		if (tab[i] > left && tab[i] < right)
		{
			tab2[wsk] = tab[i];
			wsk++;
		}
		
	}
	return tab2;
}

Następnie chciałbym tę tablicę wyświetlić i w sumie pokazuje te elementy ale wraz z tymi niepotrzebnymi liczbami na końcu, które pojawiają się bo rozmiar nie jest dostosowany (chyba :p)

screenshot-20170318145313.png

Wklejam też całą treść zadania:

screenshot-20170318150258.png

Pytanie dotyczy podpunktu "c". Pewnie cała moja koncepcja rozwiązania jest zla, ale dlatego pytam tutaj.

Z gory dzięki!

5

Bardzo przykre jest, że od początku uczą was błędnego podejścia na zajęciach (bardziej rozpisałem się tutaj). Być może powinniście kupić prowadzącemu aktualny kalendarz i poprosić aby uczył was materiału poprawnego w 2017, a nie 1995?

Z wymaganiami takimi jakie masz w zadaniu, podejrzewam, że będziesz musiał przejść przez tablicę 2 razy (zliczyć, utworzyć, skopiować), albo utworzyć tablicę o maksymalnej wielkości i w jakiś sposób oznaczyć pozostałe jako niepoprawne (coś jak NaN). Swoją drogą, ściśle trzymając się zadania nie ma ono sensu, bo nie masz jak zwrócić wielkości nowej tablicy.

Poza tym: zadanie wymaga (trochę bezsensownie) użycia operatora * do dereferencji, a Ty używasz []. Jeśli to tablica intów, to nie powinieneś używać floatów, które dla większych wartości po prostu nie będą dostatecznie dokładne.

Ogólnie pomysł masz ok, ale zadanie jest głupie.

0

Bardzo dziękuję za odpowiedź. Wszystkie rady wezmę sobie do serca :) Jest już mały postęp. Zapostuję jak tylko się z tym uporam. Jeszcze raz dzięki!

0

jak mała tablica to przejdzie też ;-)

size_t s = 0;
scanf( "%zu", &s );

int tab[s];

2

A tak w ogóle to masz UB:

int *tab2 = new int[n];
...
tab2[n] = 0;

tab2 nie ma żadnego elementu o indeksie n.

0
twonek napisał(a):

A tak w ogóle to masz UB:

int *tab2 = new int[n];
...
tab2[n] = 0;

tab2 nie ma żadnego elementu o indeksie n.

Masz rację, poprawione. Program skończyłem. Niby działa jak trzeba, ale dalej nie jest to to co chciałem osiągnąć. Dziękuję za pomoc!

1

Tak przy okazji, gdybyście mogli używać C++ w tym zadaniu, to rozwiązanie mogłoby wyglądać tak:

thread_local mt19937_64 prng{random_device{}()};

auto generate_arr(size_t size)
{
	vector<int> arr(size);
	generate(arr.begin(), arr.end(), []{
		return uniform_int_distribution<int>{0, 100}(prng);
	});
	return arr;
}

double average(vector<int> const& arr) // a
{
	return accumulate(arr.cbegin(), arr.cend(), 0.0, plus<double>{}) / arr.size();
}

double standard_deviation(vector<int> const& arr) // b
{
	auto avg = average(arr);
	double sum = accumulate(arr.cbegin(), arr.cend(), 0.0, [avg](double t, double e){
		return t + pow(avg-e, 2);
	});
	return sqrt(sum/arr.size());
}

auto elements_within(vector<int> const& arr, int middle, int radius) // c
{
	std::vector<int> ret;
	copy_if(arr.cbegin(), arr.cend(), back_inserter(ret), [=](int el){
		return abs(el-middle) < radius;
	});
	return ret;
}

void apartheidize(std::vector<int>& arr) // d
{
	auto avg = average(arr);
	partition(arr.begin(), arr.end(), [avg](int val){
		return val < avg;
	});
}

http://melpon.org/wandbox/permlink/Tu6NnND02jSagaoy

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