[C++] Usuwanie duplikatów


(Kanaliaon) #1

Dla niektórych konfiguracji liczb nie działa poprawnie, np dla n= 11 i liczb 32,3,2,5,2,4,2,3,12,2,2

Ma ktoś jakiś pomysł, dlaczego? Z góry dzięki za pomoc.

#include 


using namespace std;


int main()

{

	long int tablica[100];

	int n,e=0,licznik=0;

	cout << "Ile liczb? ";

	cin >> n;

	int ile=0;

	for(int i=0; i
	{

		cout << "Podaj liczbe numer " << i+1 << ": ";

		cin >> e;

		tablica[i]=e;

	}


	cout << endl << "Tablica przed usunieciem duplikatow: ";

	for(int j=0; j
	{

		cout << tablica[j] << ",";

	}

	cout << endl;

	for(int k=0; k
	{

		for(int l=0; l
		{

			if((tablica[k]==tablica[l]) && (l<=n) && (k!=l))

			{

				tablica[k]=tablica[k-1];

				licznik++;

			}

		}

	}

	cout << endl << "Tablica po usunieciu duplikatow: ";

	for(int o=licznik; o
	{

		cout << tablica[o] << ",";

	}

	cout << endl;

	return 0;

}

-- Dodane 08.04.2009 (Śr) 23:34 -- Udało mi się zrobić ale dla elementów niezerowych:

#include 


using namespace std;


int main()

{

	long int tablica[100];

	int n,e=0,licznik=0;

	cout << "Ile liczb? ";

	cin >> n;

	int ile=0;

	for(int i=0; i
	{

		cout << "Podaj liczbe numer " << i+1 << ": ";

		cin >> e;

		tablica[i]=e;

	}


	cout << endl << "Tablica przed usunieciem duplikatow: ";

	for(int j=0; j
	{

		cout << tablica[j] << ",";

	}

	cout << endl;

	for(int k=0; k
	{

		for(int l=0; l
		{

			if((tablica[k]==tablica[l]) && (l<=n) && (k!=l))

			{

				tablica[k]=0;

				licznik++;

			}

		}

	}

	cout << endl << "Tablica po usunieciu duplikatow: ";

	for(int o=0; o
	{

		if(tablica[o]!=0)

		cout << tablica[o] << ",";

	}

	cout << endl;

	return 0;

}

-- Dodane 09.04.2009 (Cz) 0:00 -- Ok już mam, zastosowałem swoją metodę z tablicą pomocniczą :slight_smile:

#include 


using namespace std;


int main()

{

	long int tablica[100], duplikaty[100];

	int n,e=0;

	cout << "Ile liczb? ";

	cin >> n;

	int ile=0;

	for(int i=0; i
	{

		cout << "Podaj liczbe numer " << i+1 << ": ";

		cin >> e;

		tablica[i]=e;

	}

	cout << endl << "Tablica przed usunieciem duplikatow: ";

	for(int j=0; j
	{

		cout << tablica[j] << ",";

	}

	cout << endl;

	for(int k=0; k
	{

		for(int l=k; l
		{

			if((tablica[k]==tablica[l]) && (l<=n) && (k!=l))

			{

				if(tablica[k]==tablica[l]) 

				{

					duplikaty[k]=0;

				}

			}

		}

	}

	cout << endl << "Tablica po usunieciu duplikatow: ";

	for(int o=0; o
	{

		if(duplikaty[o]!=0)

		cout << tablica[o] << ",";

	}

	cout << endl;

	system("pause");

	return 0;

}

([alex]) #2

W twojej ostatecznej wersji (jak zresztą w poprzednich):

if((tablica[k]==tablica[l]) && (l<=n) && (k!=l))

Nie ma sposobu aby zaistniało (l<=n)==false. Składową warunku (k!=l) też można pominąć o ile zaczniemy pętle po l od k+1 Twoja wersja usuwania duplikatów zakłada że wśród wartości tablicy nie może być wartości - 0. Może lepiej:

int p=0;
for(int k=0;k<n;++k)
  {
   bool UnikalnaWartosc=true; 
   for(int j=0;(j<k)&&(UnikalnaWartosc);++j) UnikalnaWartosc=(tablica[j]!=tablica[k]);
   if(UnikalnaWartosc)
     {
      if(p<k) tablica[p]=tablica[k];
      ++p;
     }
  }
n=p; //p - nowy rozmiar tablicy [/code]

Tak a propos, to chyba ty zadawałeś pytanie na temat różnicy pomiędzy ++i a i++, więc mam pytanie: Nie czytałeś odpowiedzi czy niezbyt zrozumiałeś je?


(Kanaliaon) #3

Ale ta ostatnia wersja moja chyba działa? Testowałem i działa, więc po co inne rozwiązania. A operatory preinkrementacji i postinkrementacji rozumiem.


([alex]) #4

Po pierwsze, nie działa, przenieś tablicę duplikaty jako zmienną globalną (przed main) a błąd wylezie w pełnej swojej krasie :smiley:

Po drugie, stosowanie dodatkowej tablicy rozmiarem takim jak ta oryginalna jest dosyć kiepskim podejściem dla tak prostego zagadnienia, niech przynajmniej będzie tablicą wartości logicznych.

Po trzecie, nadal nie istnieje fizycznie tablicy z usuniętymi duplikatami, owszem zaimplementowałeś drukowanie niepowtarzających się elementów ale samej tablicy brak, jakiekolwiek wcześniej napisane funkcje coś robiące na tablice na takiej wirtualnej tablice nie zadziałają, czyli jak będzie potrzebne obliczenie średniej to nie da się użyć już gotowej funkcji, trzeba taką specjalnie napisać dla tej wirtualnej tablicy.

No i po czwarte, testowałem i działa, więc po co inne rozwiązania - to podejście amatorskie a la pewien rodzaj"guru", nie należy nawet rozważać jakichkolwiek implementacji z myślą niech no tylko zadziała a później ewentualnie zoptymalizuje.

To czemu używasz przyrostkowej wersji tam gdzie można zastosować przedrostkową?


(Sawyer47) #5

Zamiast wymyślać od nowa koło nie lepiej użyć http://www.cppreference.com/wiki/stl/algorithm/unique i/lub http://www.cppreference.com/wiki/stl/al ... nique_copy ? A jeśli chodzi bardziej o sam algorytm, to można zajrzeć w źródła i zobaczyć jak tę funkcję standardową zaimplementowano.


([alex]) #6

O czym ty gadasz? Człowiek dopiero się uczy programowania, a ty chcesz aby zrozumiał kod z użyciem wzorców i iteratorów?


(Kanaliaon) #7

To jest zadanie z uczelni (politechnika - przedmiot: informatyka) i to miało być robione na elementarnych elementach języka C++ - warunki, pętle, tablice. Przez użycia gotowca w 1 linijce nic się nie nauczę...

Proszę o dalsze rady, krytykę i dzięki za dotychczasowe rady.


([alex]) #8

Tu akurat nr47, proponował nie użycie tego tylko podpatrzenie jak to jest zrobione.

Nic nowego nie wystawiłeś na odstrzał :smiley:

PS, znalazłeś błąd o którym mówiłem?