Zmiana rozmiaru tablicy

0

Zadanie: Na prośbę programu użytkownik podaje rozmiar tablicy liczb całkowitych. Następnie
program tworzy tę tablicę dynamicznie i wypełnia ją liczbami naturalnymi, tak że
komórka o indeksie i zawiera liczbę i. Następnie w nowej linii program wyświetla
zawartość tablicy. Potem program pyta o to, co zrobić:

  1. Zmienić rozmiar tablicy? Jeśli tak – program dodaje do końca tablicy odpowiednią
    liczbę nowych komórek zawierających numery ich indeksów (przy zwiększeniu rozmiaru
    tablicy) lub usuwa z końca tablicy odpowiednią liczbę komórek.
    Wymagania: Obszar tablicy ma być przydzielany i zwalniany dynamicznie. Realizacja czynności 1—4
    ma być wykonywana przez osobne funkcje, a ich wybór przez instrukcję wyboru.
#include <iostream>
using namespace std;
int* zwieksz(int *tab, int &nrozmiar, int rozmiar);
int main()
{
	int rozmiar, wybor = 5;
	cout << "Podaj rozmiar tablicy: ";
	cin >> rozmiar;
	int *tab = new int[rozmiar]; //Tworze glowna tablice
	for (int i = 0; i < rozmiar; i++) //Wypelniam
	{
		tab[i] = i;
	}
	cout << endl;
	while (wybor != 0) //Petla wykonujaca sie dopoki nie bedzie wpisane 0
	{
		for (int i = 0; i < rozmiar; i++)
		{
			cout << "Komorka "<<i<<" wynosi " << tab[i] << ", " << endl; //wyswietlenie elemtow tablicy
		}
		cout << endl << "Co teraz?\n0-Wyjdz z programu\n1-Zmien rozmiar tablicy\n2-Dolacz do konca tablicy jedna komorke podana przez uzytkownika\n" <<
			"3-Wstaw komorke z podana przez uzytkownika liczba w miejsce przed wybrana komorka\n4-Usun wybrana komorke\n"; //menu
		cin >> wybor;
		switch (wybor)
		{
		case 1: //Zmiana rozmiaru
			cout << "Podaj rozmiar nowej tablicy: ";
			int *nrozmiar = new int;
			cin >> *nrozmiar;
			if (*nrozmiar >= rozmiar)
			{
				tab = zwieksz(tab, *nrozmiar, rozmiar);
				
			}
			else cout << "\npozniej";
		}
	}
	getchar();
	getchar();
	return 0;
}
int* zwieksz(int *tab, int &nrozmiar, int rozmiar)
{
	int *ttab = new int[nrozmiar];
	for (int i = 0; i < rozmiar; i++)
	{
		ttab[i] = tab[i];
	}
	for (int i = rozmiar; i < nrozmiar; i++)
		ttab[i] = i;
	delete[]tab;
	return ttab;
} 

Problemem jest to, że program caly czas wyswietla pierwsza tablice zamiast tej ze zwiekszonym rozmiarem. Do tego pytanie jak zmiejszyc tablice (i usunac jej elementy)? Reszte opcji z menu mam zamiar oczywiscie równiez zrobic jednak na razie chce sie uporac z pierwsza :)

3

realloc

0

Problem pozostaje ten sam. Nie potrafie "przeniesc" nowo stworzonej tablicy na poczatek

 #include <iostream>
using namespace std;
int* zwieksz(int *tab, int &nrozmiar, int rozmiar);
int main()
{
	int rozmiar, wybor = 5;
	cout << "Podaj rozmiar tablicy: ";
	cin >> rozmiar;
	int * tab = (int*)calloc(rozmiar, sizeof(int));; //Tworze glowna tablice
	for (int i = 0; i < rozmiar; i++) //Wypelniam
	{
		tab[i] = i;
	}
	cout << endl;
	while (wybor != 0) //Petla wykonujaca sie dopoki nie bedzie wpisane 0
	{
		for (int i = 0; i < rozmiar; i++)
		{
			cout << "Komorka "<<i<<" wynosi " << tab[i] << ", " << endl; //wyswietlenie elemtow tablicy
		}
		cout << endl << "Co teraz?\n0-Wyjdz z programu\n1-Zmien rozmiar tablicy\n2-Dolacz do konca tablicy jedna komorke podana przez uzytkownika\n" <<
			"3-Wstaw komorke z podana przez uzytkownika liczba w miejsce przed wybrana komorka\n4-Usun wybrana komorke\n"; //menu
		cin >> wybor;
		switch (wybor)
		{
		case 1: //Zmiana rozmiaru
			cout << "Podaj rozmiar nowej tablicy: ";
			int *nrozmiar = new int;
			cin >> *nrozmiar;
			int* new_tab = (int*)realloc(tab, (*nrozmiar) *sizeof(int));
			for (int i = rozmiar; i < *nrozmiar; i++)
				new_tab[i] = i;
			for (int i = 0; i < *nrozmiar; i++)
				tab[i] = new_tab [i];
			delete[] new_tab;

		}
	}
	getchar();
	getchar();
	return 0;
}

Przykladowo na poczatku tworze 2 elemtowa tablice i wyswietlam jej elemnty, nastepnie zwiekszam ja do 5 elementow, jednak program wciaz wyswietla tylko 2. Przy zmniejszaniu tez nie dziala tak jak powinno

0
            cout<<"Podaj rozmiar nowej tablicy: ";
            cin>>rozmiar;
            tab=(int*)realloc(tab,rozmiar*sizeof(int));

i nic więcej, no ewentualnie sprawdzić czy nie zwróciło NULL - czyli brak pamięci.

0

Nie moge tak zrobic, poniewaz przy zwiekszeniu tablicy nowe elementy maja dziwne wartosci (-842150451)

 int main()
{
	int rozmiar, wybor = 5;
	cout << "Podaj rozmiar tablicy: ";
	cin >> rozmiar;
	int * tab = (int*)calloc(rozmiar, sizeof(int));; //Tworze glowna tablice
	for (int i = 0; i < rozmiar; i++) //Wypelniam
	{
		tab[i] = i;
	}
	cout << endl;
	while (wybor != 0) //Petla wykonujaca sie dopoki nie bedzie wpisane 0
	{
		for (int i = 0; i < rozmiar; i++)
		{
			cout << "Komorka "<<i<<" wynosi " << tab[i] << ", " << endl; //wyswietlenie elemtow tablicy
		}
		cout << endl << "Co teraz?\n0-Wyjdz z programu\n1-Zmien rozmiar tablicy\n2-Dolacz do konca tablicy jedna komorke podana przez uzytkownika\n" <<
			"3-Wstaw komorke z podana przez uzytkownika liczba w miejsce przed wybrana komorka\n4-Usun wybrana komorke\n"; //menu
		cin >> wybor;
		switch (wybor)
		{
		case 1: //Zmiana rozmiaru
		{
			cout << "Podaj rozmiar nowej tablicy: ";
			int nrozmiar = 0;
			cin >> rozmiar;
			tab = (int*)realloc(tab, rozmiar*sizeof(int));
			if (nrozmiar > rozmiar)
				for (int i = rozmiar; i < nrozmiar; i++)
					tab[i] = i;
		}
			break;
		case 2:                                              //Nie skonczony jeszcze
			int liczba;
			cout << "Podaj liczbe: ";
			cin >> liczba;
			int *tt;
			tt = new int[rozmiar + 1];
			for (int i = 0; i<rozmiar; i++)
				tt[i] = tab[i];
			tt[rozmiar] = liczba;
			delete[]tab;
			tab = tt;
		}

	}
	getchar();
	getchar();
	return 0;
}

Zrobilem tak ale dalej nie dziala

0

Jakiego słowa w zdaniu: - "i nic więcej" - nie zrozumiałeś?
Nie trzeba: żadnych if'ów, zadnych for'ów, żadnych nrozmiar'ów

0

Próbowałem. I tak jak pisalem, przy zwiekszaniu tablicy nowe elementy maja złą wartość.

 #include <iostream>
using namespace std;
int* zwieksz(int *tab, int &nrozmiar, int rozmiar);
int main()
{
	int rozmiar, wybor = 5;
	cout << "Podaj rozmiar tablicy: ";
	cin >> rozmiar;
	int * tab = (int*)calloc(rozmiar, sizeof(int));; //Tworze glowna tablice
	for (int i = 0; i < rozmiar; i++) //Wypelniam
	{
		tab[i] = i;
	}
	cout << endl;
	while (wybor != 0) //Petla wykonujaca sie dopoki nie bedzie wpisane 0
	{
		for (int i = 0; i < rozmiar; i++)
		{
			cout << "Komorka "<<i<<" wynosi " << tab[i] << ", " << endl; //wyswietlenie elemtow tablicy
		}
		cout << endl << "Co teraz?\n0-Wyjdz z programu\n1-Zmien rozmiar tablicy\n2-Dolacz do konca tablicy jedna komorke podana przez uzytkownika\n" <<
			"3-Wstaw komorke z podana przez uzytkownika liczba w miejsce przed wybrana komorka\n4-Usun wybrana komorke\n"; //menu
		cin >> wybor;
		switch (wybor)
		{
		case 1: //Zmiana rozmiaru
		{
			cout << "Podaj rozmiar nowej tablicy: ";
			cin >> rozmiar;
			tab = (int*)realloc(tab, rozmiar*sizeof(int));
		}
			break;
		case 2:
			int liczba;
			cout << "Podaj liczbe: ";
			cin >> liczba;
			int *tt;
			tt = new int[rozmiar + 1];
			for (int i = 0; i<rozmiar; i++)
				tt[i] = tab[i];
			tt[rozmiar] = liczba;
			delete[]tab;
			tab = tt;
		}

	}
	getchar();
	getchar();
	return 0;
}

Po stworzeniu tablicy 3 elementowej, a nastepnie zwiekszeniu jej do 6 elementowej nowe komorki maja wartosc -842150451

3

NIE wolno mieszać malloc/realloc/calloc/free z new/delete!!!

EDIT:
@T0ny
Dodatkowo: W przeciwieństwie do calloc, realloc NIE inicjalizuje alokowanych elementów. calloc wstawia Ci same zera, realloc — śmieci. Mało tego, odwołanie się do wartości zostawionych przez realloc to jest tzw. undefined behaviour, co w skrócie oznacza, że Twój program może się rozchranić na pierdylion różnych sposobów i że jest to błąd sam w sobie. Jeśli używasz realloc, to MUSISZ potem wstawić tam ręcznie sensowniejsze wartości — najlepiej natychmiast, a najpóźniej zanim się do nich odwołasz. Przepraszam, machnąłem się trochę rzeczywiście.

0

Jeśli kogoś faktycznie interesuje rozwiązanie to zamieszczam cały kod z pozostałymi case'ami (możliwe, że da się nieco krócej):

 #include <iostream>
using namespace std;
int main()
{
	int rozmiar, wybor = 5;
	cout << "Podaj rozmiar tablicy: ";
	cin >> rozmiar;
	int *tab;
	tab = new int[rozmiar]; 
	for (int i = 0; i < rozmiar; i++) 
	{
		tab[i] = i;
	}
	cout << endl;
	while (wybor != 0)
	{
		for (int i = 0; i < rozmiar; i++)
		{
			cout << "Komorka "<<i<<" wynosi " << tab[i] << ", " << endl; 
		}
		cout << endl << "Co teraz?\n0-Wyjdz z programu\n1-Zmien rozmiar tablicy\n2-Dolacz do konca tablicy jedna komorke podana przez uzytkownika\n" <<
			"3-Wstaw komorke z podana przez uzytkownika liczba w miejsce przed wybrana komorka\n4-Usun wybrana komorke\n";
		cin >> wybor;
		switch (wybor)
		{
		case 1:
		{
			cout << "Podaj rozmiar nowej tablicy: ";
			int nrozmiar;
			cin >> nrozmiar;
			int *tt;
			tt = new int[nrozmiar];
			if (nrozmiar < rozmiar)
			{
				for (int i = 0; i < nrozmiar; i++)
					tt[i] = tab[i];
			}
			else
			{
				for (int i = 0; i < rozmiar; i++)
					tt[i] = tab[i];
				for (int i = rozmiar; i < nrozmiar; i++)
					tt[i] = i;
			}
			rozmiar = nrozmiar;
			delete[]tab;
			tab = tt;
		}
		break;
		case 2:
			int liczba;
			cout << "Podaj liczbe: ";
			cin >> liczba;
			int *tt;
			rozmiar = rozmiar + 1;
			tt = new int[rozmiar];
			for (int i = 0; i < rozmiar - 1; i++)
				tt[i] = tab[i];
			tt[rozmiar - 1] = liczba;
			delete[]tab;
			tab = tt;
			break;
		case 3:
		{
			cout << "Podaj liczbe jaka ma byc wstawiona: ";
			int liczba;
			cin >> liczba;
			cout << "Podaj komorke przed ktora ma byc wstawiona liczba: ";
			int komorka;
			cin >> komorka;
			int *tt;
			rozmiar = rozmiar + 1;
			tt = new int[rozmiar];
			for (int i = 0; i < rozmiar - 1; i++)
				tt[i] = tab[i];
			tt[komorka-1] = liczba;
			tt[rozmiar-1] = rozmiar-1;
			delete[]tab;
			tab = tt;
			break;

		}
		case 4:
		{
			cout << "Ktora komorke usunac? ";
			int komorka;
			cin >> komorka;
			int *tt;
			rozmiar = rozmiar - 1;
			tt = new int[rozmiar];
			for (int i = 0; i < komorka; i++)
				tt[i] = tab[i];
			for (int i = komorka; i < rozmiar; i++)
				tt[i] = tab[i+1];
			delete[]tab;
			tab = tt;

		}
		}
	}
	getchar();
	getchar();
	return 0;
}

Jak się okazuje nie trzeba realloc'ów i malloc'ów, za to for'y i if'y są dość przydatne :)

2
  1. zapoznaj się z pojęciem formatowania: http://4programmers.net/Forum/998482
  2. zapoznaj się z inkrementacją, bo jej nie rozumiesz: http://4programmers.net/Forum/1101404
  3. zapoznaj się z funkcją memcpy jest istotnie szybsza od for np zamiast litanii:
            if (nrozmiar < rozmiar)
            {
                for (int i = 0; i < nrozmiar; i++)
                    tt[i] = tab[i];
            }
            else
            {
                for (int i = 0; i < rozmiar; i++)
                    tt[i] = tab[i];
                for (int i = rozmiar; i < nrozmiar; i++)
                    tt[i] = i;
            }

wystarczy:

            memcpy(tt,tab,(nrozmiar<rozmiar?nrozmiar:rozmiar)*sizeof(int)); // zamiast ?: można użyć `std::min()`, kto co lubi
            for (int i=rozmiar;i<nrozmiar;++i) tt[i]=i;
  1. zapoznaj się z pojęciem funkcji, bez sensu masz zmianę rozmiaru tablicy w 5-ciu miejscach
  2. no i jak napisał już w komentarzu @kaczus, zapomniałeś zwolnić pamięć

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