[C++]Zbiór.

Mikolaj9
Użytkownik
Użytkownik
Posty: 535
Rejestracja: 19 gru 2008, o 15:52
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 49 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Mikolaj9 »

Zadanie polega na utworzeniu klasy "zbiór", która będzie miała takie same właściwości i możliwości jak zbiór matematyczny.

Mój pomysł jest taki, żeby była to tablica wskaźników na flołty (tablicy flołtów nie biorę pod uwagę, bo musi istnieć komórka z adresem null, która będzie oznaczać koniec zbioru i jego pustość jeśli wystąpi na pierwszym miejscu tablicy).

I teraz moje dwa pytania:

Czy pomysł jest dobry (to znaczy, czy jest to wykonalne w ten sposób)?

Jak będzie wyglądał konstruktor?




Ja próbowałem to robić mniej więcej tak, ale coś nie działa. Chodzi mi głównie o ten początek:

class zbior{

float** elementy;

public:

zbior(){
elementy=new float*[SIZE];
elementy[0]=NULL;
}

....

};
Tomcat
Użytkownik
Użytkownik
Posty: 327
Rejestracja: 23 mar 2009, o 21:51
Płeć: Mężczyzna
Lokalizacja: Świdnica
Podziękował: 10 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Tomcat »

Wykonalne jest, generalnie ten problem można rozwiązać na kilka(kilkanaście sposobów). Dobrze, że planujesz użyć tablicy wskaźników (chociaż argument że potrzebny jest jakiś znacznik zbioru nie przemawia do mnie IMHO lepiej byłoby dodać np licznik który przechowuje ile jest elementów w zbiorze) dlatego, że bardziej dbasz w taki sposób o pamięć. A konstruktor masz dobry, generalnie idea jest w porządku. Pokaż więcej kodu to będziemy mogli obgadać konkretne rozwiązania.
Mikolaj9
Użytkownik
Użytkownik
Posty: 535
Rejestracja: 19 gru 2008, o 15:52
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 49 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Mikolaj9 »

Zacząłem robić to trochę inaczej. Utworzyłem tablicę flołtów, i taki właśnie licznik elementów. Tak będzie dobrze? Pewnie wyskoczą jakieś problemy, to będę tu pisał jakby co. Dzięki.
Tomcat
Użytkownik
Użytkownik
Posty: 327
Rejestracja: 23 mar 2009, o 21:51
Płeć: Mężczyzna
Lokalizacja: Świdnica
Podziękował: 10 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Tomcat »

Będzie dobrze ale jak się piszę coś pierwszy raz to bugi to rzecz normalna więc w razie wątpliwości pytaj tutaj i od razu wrzucaj trochę kodu żebyśmy wiedzieli o czym rozmawiamy.
Mikolaj9
Użytkownik
Użytkownik
Posty: 535
Rejestracja: 19 gru 2008, o 15:52
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 49 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Mikolaj9 »

No to już mam kilka problemów:

1. Operator sumy, różnicy iloczynu. Mam z nimi ten sam problem. Kiedy piszę xxl=xxx+t, albo c=a-b, wyskakuje mi dokładnie takie coś:
no match for 'operator=' in xxl = set::operator+(set)(set(((set&)(&t)))'
Moje operatory:
Ukryta treść:    




2. Operator wyjścia <<. Wewnątrz klasy deklaruje operator wyjscia tak:

friend ostream & operator<< (ostream & ekran, set &x);

i poza klasą:

Ukryta treść:    


I kompilator krzyczy, że ten operator jest wielokrotnie zdefiniowany. "Multiple definition of 'operator<<...'

A i jeszcze jedno. Jak napisać funkcję, która przy wypisywaniu zbioru poda też jego nazwę?
Tomcat
Użytkownik
Użytkownik
Posty: 327
Rejestracja: 23 mar 2009, o 21:51
Płeć: Mężczyzna
Lokalizacja: Świdnica
Podziękował: 10 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Tomcat »

1. Zaimplementowałeś operator przypisania, ale czy nie zapomniałeś o konstruktorze kopiującym? Poczytaj o nim na necie. Domyślam się, że stworzyłeś własny konstruktor więc kompilator tu za Ciebie nie zadziała, dopisz konstruktor kopiujący, problemy powinny zniknąć.

W 2. nie wiem co jest nie tak pokaż dokładnie linijkę kodu o którą krzyczy kompilator i treść błędu.

Co rozumiesz pod nazwą zbioru? Jeżeli przechowujesz w zmiennej składowej to nie ma problemu. Jeżeli chciałbyś wypisać nazwę zmiennej to z tego co wiem to można, gdzieś w Sieci nawet kiedyś coś takiego widziałem, ale szczerze po co Ci to? Rozwiązanie ze zmienną jest najlepsze.
Mikolaj9
Użytkownik
Użytkownik
Posty: 535
Rejestracja: 19 gru 2008, o 15:52
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 49 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Mikolaj9 »

1. Konstruktor kopiujący mam:

set(set &tmp):power(tmp.power){
elems=new float[MAX];
for(int i=0; i<=power; i++)
elems=tmp.elems;
}


2.
multiple definition of 'operator<<(std::ostream&, set&)'
first defnifed here (nie wiem co ma oznaczać to here - nie pokazuje numeru linijki)
ld returned exit status
[Build Error][PROJEKT.exe]Error1


Z nazwą zbioru chodzi mi o to, że jak deklaruje zbiór
set abc;
to żeby funkcja wypisująca zbiór pisała "abc:{x,y,z}"
spajder
Użytkownik
Użytkownik
Posty: 735
Rejestracja: 7 lis 2005, o 23:56
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 2 razy
Pomógł: 133 razy

[C++]Zbiór.

Post autor: spajder »

Nie ma szans, przy kompilacji giną informacje nazwach zmiennych. Lepiej przechowuj nazwę zbioru w polu wewnątrz klasy, konstruktor natomiast niech ustawia to pole:

Kod: Zaznacz cały

Set(const std::string &name);
Na upartego można kombinować za pomocą preprocesora, ale absolutnie tego nie polecam:

Kod: Zaznacz cały

#define SET(a) set a("a");
I tworzyć zbiór w ten sposób;

Kod: Zaznacz cały

SET(mojZbior);
Dodatkowo polecam ten operator wypisania zadeklarować jako:

Kod: Zaznacz cały

std::ostream& operator<<(std::ostream&, const set&);
Co do błędu - to jest komunikat linkera, że stworzyłeś dwie wersje operatora <<. Jak klikniesz 2 razy w linijkę z wyrazem here to powinno skoczyć do odpowiedniego miejsca w kodzie. Być może zdefiniowałeś tą funkcję w 1 pliku, ale 2 razy ten plik włączasz.

BTW. power set oznacza zbiór potęgowy, cardinality to moc zbioru :d
Tomcat
Użytkownik
Użytkownik
Posty: 327
Rejestracja: 23 mar 2009, o 21:51
Płeć: Mężczyzna
Lokalizacja: Świdnica
Podziękował: 10 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Tomcat »

Słusznie prawi spajder

Tak jak sam wyżej pisałem, wypisanie nazwy zbioru tak jak masz to w kodzie zapisane to się nie da, musisz gdzieś przechowywać jego nazwę.

Co do operatora << to zrób dwie rzeczy. Najpierw napisz explicite z jakiej przestrzeni nazw (namespace) korzystasz, tzn przed każdym ostream daj std:: Po drugie sprawdź czy w pliku nagłówkowym masz tzw. compilation guards, tzn:

Kod: Zaznacz cały

#ifndef MOJ_PLIK_H
#define MOJ_PLIK_H
/*
Tu masz swój kod
*/
#endif
Mikolaj9
Użytkownik
Użytkownik
Posty: 535
Rejestracja: 19 gru 2008, o 15:52
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 49 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Mikolaj9 »

Dobra, tą nazwę zbioru sobie odpuszczę, zrobię ją po prostu jako element klasy.
Problem z operatorem << rozwiązało wstawienie tych "compilation guards".
Ostatni problem, który został, to operatory dodawania, odejmowania etc., nie wiem czym spowodowany.
spajder
Użytkownik
Użytkownik
Posty: 735
Rejestracja: 7 lis 2005, o 23:56
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 2 razy
Pomógł: 133 razy

[C++]Zbiór.

Post autor: spajder »

Czy w tamtej linijce Ty na pewno dodajesz zbiór do zbioru? Bo mam wrażenie (po komunikacie), że próbujesz dodać element do zbioru, a wtedy musisz utworzyć nowy operator dodawania:

Kod: Zaznacz cały

set operator+(const set&, float);
// albo mozna tez tak
set& operator+(set&, float);
// tylko tutaj musisz zwrocic edytowany zbior i dodawanie elementow go zmieni, tj jak napiszesz
// set a = b + x;
// to zmieni sie zarowno zbior a jak i zbior b
// z drugiej strony da sie to zaimplementowac duzo szybciej :p
ps. i operator przypisania zmień tak, aby przyjmował jako parametr referencję do stałej
Fibik
Użytkownik
Użytkownik
Posty: 971
Rejestracja: 27 wrz 2005, o 22:56
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 11 razy
Pomógł: 75 razy

[C++]Zbiór.

Post autor: Fibik »

Do czego mają służyć te wskaźniki do floatów?

Element należy do zbioru lub nie... czyli tablica bitów.

Zbiór o mocy N, czyli mamy maksimum N różnych elementów, zatem N bitów, czyli (N + 7)/8 bajtów.

potem operatory: +, -, xor, not, neg, ... operacje wykonujemy normalnie na tych bitach.
Mikolaj9
Użytkownik
Użytkownik
Posty: 535
Rejestracja: 19 gru 2008, o 15:52
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 49 razy
Pomógł: 62 razy

[C++]Zbiór.

Post autor: Mikolaj9 »

@Spajder
To co próbuje zrobić, operatorem, to utworzenie sumy dwóch zbiorów i przypisanie do innego zbioru xxl, bez zmiany zbioru xxx i t.

edit: aaa, już wiem o co chodziło, faktycznie, miałem błąd w tym operatorze. Teraz zmieniłem, i się kompiluje, ale coś nie działa. To znaczy nie chce mi dodawać drugiego zbioru do "this'a"

Mam go napisanego tak:

set operator+(set a)
{
set nowy(*this)
for(int i=0; i<a.power;i++)
nowy.push(a.elems);
return nowy;
}

@Fibik.
Robię to już w inny zupełnie sposób.

-- 16 stycznia 2010, 22:06 --

Ok, już ponaprawiałem wszystko, tak że zbiór działa jak należy.

Ostatnia już rzecz tylko. Chodzi o operator >> - kompletnie nie wiem jak go zacząć. Jego działanie ma polegać na ładowaniu po kolei flołtów do zbioru ze standardowego wejscia.
ODPOWIEDZ