PDA

View Full Version : Xây dựng lớp tập hợp Set



SUPER KUNG FU
28-04-2009, 14:08
xây dựng lớp set với các phần tử là số nguyên.
Yêu cầu:
-Có phương thức thiết lập không tham số khởi tạo đối tượng là tập rỗng
-Có phương thức thiết lập 1 tham số kiểu mảng các số nguyên để khởi tạo tập hợp với các phần tử của mảng.
-Có phương thức hiển thị tập hợp
-Cài đặt các phép toán hợp , giao, hiệu. Xây dựng chương trình minh họa.

ptaminh
28-04-2009, 14:15
Vấn đề ở đây là gì ?

SUPER KUNG FU
28-04-2009, 14:29
Mình không biết làm nên đưa ra nhờ mọi người

ptaminh
28-04-2009, 15:09
Mình không biết làm nên đưa ra nhờ mọi người

Ok! Mới xong project nên hiện tại hơi rảnh.



class Set
{
private:
int* m_a;
int m_Length;

public:

const int* GetData() const
{ return m_a;}
int GetLength()const
{ return m_Length;}

Set(){
m_a = NULL;
m_Length = 0;
}

Set(int* a, int Length){
// duyệt từng phần tử trong mảng a
// thêm từng phần tử dùng toán tử + bên dưới
}

// constructor copy
Set(const Set set)
{
m_Length = set.GetLength();
m_a = (int*)malloc(Length *sizeof(int));
memcpy(m_a,set.GetData, Length*sizeof(int));
}

~Set()
{
if(m_a) free(m_a);
}

void Output() const
{
// duyệt mảng và xuất từng phần tử => ko có gì để bàn.
}
// phương thức tìm kiếm một phần tử có tồn tại hay không
int Find(int Key) const
{
// duyệt mảng tìm vị trí của phần từ cần tìm
// thấy trả về vị trí của nó trong mảng
// nếu không trả về -1.
}
//toán tử thêm một phần tử vào tập hợp
Set& operator+(int Key)
{
// nếu phần từ không tồn tại trong mảng => thêm vào cuối mảng
// nếu tồn tại không thêm gì hết.
if(Find(Key) < 0)
{
int* a = (int*) malloc ( (m_Length + 1) * sizeof(int));
if(m_Length)
memcpy(a,m_a, m_Length*sizeof(int));
a[ m_Length] = Key;
m_Length++;
}

return this;
}

//toán tử hợp
static Set operator+(const Set& set1,const Set& set2)
{
Set set = set1;
// thêm lần lượt từng phần tử của set2 vào set dùng toán tử +
...
return set;
}

//toán tử giao
static Set operator*(const Set& set1,const Set& set2)
{
Set set; // khoi tao rong
// duyệt các phần tử của set 1
// nếu tồn tại phần tử đó trong set 2 thì thêm phần từ đó vo set
// dùng toán tử +
...
return set;
}

};


các phương thức còn lịa bạn nên tự cài đặt. Mô hình và gợi ý đã có sẵn

Có chỗ nào không hiểu ko ?

thenao_layeu
27-05-2009, 15:53
Ah.Cảm ơn anh nhiều nha.Nhưng em chỉ không hiểu là:
Có phải" Set(){
m_a = NULL;
m_Length = 0;
}
là để khởi tạo lớp ban đầu là tập rỗng không ?
và còn :
// constructor copy
Set(const Set set)
{
m_Length = set.GetLength();
m_a = (int*)malloc(Length *sizeof(int));
memcpy(m_a,set.GetData, Length*sizeof(int));
}
là sử dụng constructor để làm gì vậy ?
Mong anh sẽ trả lời sớm.Cảm ơn nhiều.

ptaminh
27-05-2009, 19:09
Set() là constuctor để khởi tạo tập hợp.

khi khai báo Set A; thì A được khởi tạo là tập rỗng.

Còn Set(const Set set) bạn sửa lại giùm thành Set(const Set& set);

xét hàm dưới đây.


static Set operator+(const Set& set1,const Set& set2)
{
Set set = set1;
// thêm lần lượt từng phần tử của set2 vào set dùng toán tử +
...
return set;
}


ngay trước lệnh return set.
Cấu tứ sao chép được gọi (nếu có constructor Set(const Set&))
Hàm sao chép mặc định được gọi (nếu ko có constructor Set(const Set&))
Hủy tử được gọi
return đối tượng sao chép

Hàm sao chép mặc định sẽ làm như sau :

chép từng byte của đối tượng set vào vùng nhớ mới. do đó đối tượng mới sẽ có cùng địa chỉ con trỏ (m_a) trỏ tới vùng dữ liệu.

Nhưng vùng dữ liệu mà set.m_a đang trỏ tới đã bị free bởi hủy tử trước khi return. do đó đối tượng được trả về có dữ liệu rác và gây lỗi sau khi hủy tử của đối tượng mới này được gọi (Nếu ko có contructor copy).

nếu chưa hiểu bạn chạy ví dụ bên dưới.

và xóa hàm Set(const Set& set); rồi chạy lại lần nữa.

So sánh 2 lần chạy



class Set
{

public:
char* c;
Set()
{
c = new char;
}

Set(const Set& set)
{
c = new char;
*c = *set.c;
printf("\n Ham tao sao chep cua doi tuong %c duoc goi",*c);
}
~Set()
{
printf("\n Huy tu cua doi tuong %c duoc goi",*c);
delete c;
}

};

Set someFunc()
{
Set a;
*a.c = 'a';
return a;
}

int _tmain(int argc, _TCHAR* argv[])
{
Set b = someFunc();
*b.c = 'b';
return 0;
}

thenao_layeu
28-05-2009, 08:31
thanks anh nha.
Để em chạy thử đã.
Có gì không hiểu nhờ anh chỉ thêm nha.
Em đang đi xây dựng lớp tập hợp theo đề bài của giảng viên.
Nhưng đề chi có 1 câu là xây dựng lớp tập hợp à, không nói gì thêm hết.
Theo anh thì xây dựng lớp tập hợp này có giống như bài của anh làm không ?
Hay em phải làm gì ?
Nhờ anh tư vấn giúp em nha.
Thanks

ptaminh
28-05-2009, 12:56
Tập hợp là một mảng nhưng các phần tử trong nó đôi một khác nhau.

Nó có các phép toán, giao (*), hợp (+), trừ (-).

Khi xây dựng lớp này cũng cần thêm một số phương thức râu ria nhưng cần thiết như lấy số phần tử, thêm một phần tử vào tập hợp, tìm kiếm...

nếu bạn xài mô hình của tui cần thêm phép toán trừ (-) tập hợp.

thenao_layeu
28-05-2009, 14:19
Phương thức và phép toán khác nhau chỗ nào vậy ?
Khi nào thì nên cài đặt nó là phép toán và khi nào thi cài đặt là phương thức ?
Em chưa rõ lắm về vấn đề này.Dù có biết là phương thức thì được đặt trong phần public của class nhưng vẫn chưa hiểu phép toán thì khác với phương thức chỗ nào ?
Anh có thể giải thích giúp em không ạ !
Thanks anh nha !

ptaminh
28-05-2009, 17:50
phép toán ở đây tui dùng thay cho toán tử. giống như + - * / đó mà.

Để thực hiện một phép giao giữa 2 tập hợp một cách tự nhiên nhất

Set a = b * c;

thay vì a = b.giao(c).

thenao_layeu
29-05-2009, 08:02
Vâng,cái đó thì em hiểu rùi !
Em chỉ muốn hỏi là phép toán có nên cài đặt thành phương thức hay không thui .
Em đọc sách cũng hiểu sơ sơ rùi !
Bữa nào viết xong em post lên nhờ anh sữa dùm nha.