Thiết kế lớp tập hợp Set

Một phần của tài liệu (LUẬN văn THẠC sĩ) lược đồ cơ sở dữ liệu chuẩn hóa (Trang 37)

6. Cấu trúc của luận văn

3.2. Thiết kế lớp tập hợp Set

3.2.1 Các thuộc tính của lớp Set

Ta định nghĩa kiểu dữ liệu BS như sau:

const int __SETSIZE = 26; typedef bitset<__SETSIZE> BS;

Trong lớp Set thuộc tính Data được định nghĩa là:

BS Data;

Như vậy, Data là trường dữ liệu chứa 0-25 bit

3.2.2 Các phương thức của lớp Set

Tạo tử (constructor)

Cú pháp

inline Set() { Data.reset();

}

Ý nghĩa: Khởi tạo tập rỗng

inline Set(const string s) {

Data.reset();

for (int i = 0; i < s.length(); ++i)

if (IsAlpha(s[i]))

Data.set(Code(s[i]));

}

Ý nghĩa: Khởi tạo Set nhận giá trị từ chuỗi s Ví dụ: Set x(“ABC”);

Khi đó x chứa 2 phần từ A, B, C

Cú pháp

inline Set(const Set &x) {

Data = x.Data; }

Ý nghĩa: Khởi tạo Set nhận giá trị của tập x cho trước Ví dụ:

Set x(“ABC”);

Set y(x);

Khởi tạo x chứa 3 phần từ A, B, C

Set y(x) khởi tạo tập y nhận các giá trị của tập x là 3 phần từ A, B, C Cú pháp

inline void Reset() {

Data.reset();

}

Ý nghĩa: Reset một tập thành tập rỗng

Toán từ gán

inline void operator =(const string s) { Data.reset();

for (int i = 0; i < s.length(); ++i) if (IsAlpha(s[i]))

Data.set(Code(s[i])); }

Ý nghĩa : Gán một chuỗi từ tập x

Lấy giá trị của tập hợp

Cú pháp

inline char operator[](int i) const {

if (i >= 0 && i < __SETSIZE) {

if (Data[i])

return (Data[i]) ? ToAlpha(i) : NULL; }

return NULL; }

Ý nghĩa: Lấy phần từ thứ i cuả tập hợp.

Kiểm tra tập hợp có phải là tập rỗng hay không

Cú pháp

inline bool Empty() const {return Data.none();}

Ý nghĩa:

Kiểm tra một phần tử có thuộc tập hợp hay không

Cú pháp

inline bool IsIn(char e) {

if (IsAlpha(e)) return Data[Code(e)]; return 0; } Lực lượng của tập hợp Cú pháp

inline int Card() const {return Data.count();

Ý nghĩa: trả về số của tập hợp

Thêm phần tử vào tập hợp

inline void Ins(char e) { if (IsAlpha(e))

Data.set(Code(e)); }

Ý nghĩa : Thêm phần từ e vào tập x

Xóa phần từ

Cú pháp

inline void Del(char e) { if (IsAlpha(e)) Data.reset(Code(e)); } Ý nghĩa : Xóa phần tử e từ tập hợp Thêm phần tử Cú pháp

inline void Add(char e) {Ins(e);

Ý nghĩa: Thêm phần tử e vào tập hợp

3.2.3 Các phép toán tập hợp

Hợp của hai tập hợp

Cú pháp

Set operator +(const Set &y) const { Set z(*this);

z.Data |= y.Data; return z;

}

inline void operator +=(const Set &y) { *this = *this + y;

}

Ý nghĩa: Trả về hợp của 2 tập hợp

Giao của hai tập hợp

Cú pháp

Set operator *(const Set &y) const { Set z(*this);

z.Data &= y.Data; return z;

}

inline void operator *=(const Set &y) { *this = *this * y;

}

Ý nghĩa: Trả về giao của 2 tập hợp

Hiệu củahai tập hợp

Cú pháp

Set operator -(const Set &y) const { Set z;

for (int i = 0; i < __SETSIZE; ++i) if (Data[i] && (!y.Data[i]))

z.Data[i] = 1; return z;

}

inline void operator -=(const Set &y) {

*this = *this - y;

}

Ý nghĩa: Trả về hiệu của 2 tập hợp

So sánh hai phần tử So sánh bằng

Cú pháp

inline bool operator ==(const Set & y) const {

return Data == y.Data;

}

Ý nghĩa: So sánh hai tập hợp có bằng nhau hay không

So sánh khác

Cú pháp

inline bool operator !=(const Set & y) const {

return Data != y.Data;

}

Ý nghĩa: So sánh hai tập hợp có khác nhau hay không

So sánh nhỏ hơn hoặc bằng

Cú pháp

inline friend bool operator <=(const Set & x, const Set & y){ for (int i = 0; i < __SETSIZE; ++i)

if (x.Data[i] && (!y.Data[i])) return false;

return true; }

Ý nghĩa: So sánh hai tập hợp có nhỏ hơn hoặc bằng nhau không.

So sánh lớn hơn hoặc bằng

Cú pháp

inline friend bool operator >=(const Set & x, const Set & y){

return y <= x;

}

Ý nghĩa: So sánh hai tập hợp có lớn hơn hoặc bằng nhau không.

So sánh nhỏ hơn

Cú pháp

friend bool operator <(const Set & x, const Set & y) { return((x <= y) && (x != y));

}

Ý nghĩa: So sánh hai tập hợp có nhỏ hơn không

So sánh lớn hơn

Cú pháp

inline friend bool operator >(const Set & x, const Set & y) {

return y < x;

}

Ý nghĩa: So sánh hai tập hợp có lớn hơn không

Hiển thị

Cú pháp

friend ostream & operator <<(ostream & os, const Set & s) { if (s.Empty()) {

os << "{}"; return os; }

for (int i = 0; i < __SETSIZE; ++i) { if (s.Data[i]) os << ToAlpha(i); } return os; } Ý nghĩa: Hiển thị các phần tử ra màn hình Cú pháp

cout << msg; if (Empty()) {

cout << "{}"; return; }

for (int i = 0; i < __SETSIZE; ++i) { if (Data[i])

cout << ToAlpha(i); }

} }

Ý nghĩa: Hiển thị các phần tử ra màn hình và kèm theo thông báo msg

Ví dụ: Chương trình Demoset.cpp thực hiện các thao tác như sau: 1. Khai báo tập x, y

2. So sánh tập x có lớn hơn hoặc bằng tập y hay không 3. Hiển thị ra màn hình tập x, y

Như vậy ta thu được

/****************************************** Demoset.cpp *************************************************/ #include <iostream> #include <fstream> #include <bitset> using namespace std;

const int __SETSIZE = 26; const int __UNIT = 16;

typedef bitset<__SETSIZE> BS; class Set { protected: BS Data; public: inline Set() { Data.reset(); }

inline Set(const string s) { Data.reset();

for (int i = 0; i < s.length(); ++i) if (IsAlpha(s[i]))

Data.set(Code(s[i])); }

inline Set(const Set &x) { Data = x.Data;

}

inline void Reset() {

Data.reset();

}

inline void operator =(const Set & y) { Data = y.Data;

}

inline void operator =(const string s) { Data.reset();

for (int i = 0; i < s.length(); ++i) if (IsAlpha(s[i]))

Data.set(Code(s[i])); }

inline char operator[](int i) const { if (i >= 0 && i < __SETSIZE) {

if (Data[i])

return (Data[i]) ? ToAlpha(i) :

NULL;

}

return NULL; // (char)0; }

inline bool Empty() const {return Data.none();}

inline bool IsIn(char e) {

if (IsAlpha(e))

return Data[Code(e)];

return 0;

}

inline bool Has(char e) {return IsIn(e);}

inline int Card() const {return Data.count();}

inline void Ins(char e) { if (IsAlpha(e))

Data.set(Code(e)); }

inline void Del(char e) {

if (IsAlpha(e))

Data.reset(Code(e)); }

inline void Add(char e) {Ins(e);}

Set operator +(const Set &y) const { Set z(*this);

z.Data |= y.Data; return z;

inline void operator +=(const Set &y) {

*this = *this + y;

}

Set operator *(const Set &y) const { Set z(*this);

z.Data &= y.Data; return z;

}

inline void operator *=(const Set &y) {

*this = *this * y;

}

Set operator -(const Set &y) const { Set z;

for (int i = 0; i < __SETSIZE; ++i) if (Data[i] && (!y.Data[i]))

z.Data[i] = 1; return z;

}

inline void operator -=(const Set &y) {

*this = *this - y;

}

inline bool operator ==(const Set & y) const {

return Data == y.Data;

}

inline bool operator !=(const Set & y) const {

return Data != y.Data;

}

inline friend bool operator <=(const Set & x, const

Set & y) {

for (int i = 0; i < __SETSIZE; ++i)

if (x.Data[i] && (!y.Data[i]))

return false;

return true;

}

inline friend bool operator >=(const Set & x, const

Set & y) {

return y <= x;

}

friend bool operator <(const Set & x, const Set &

y) {

return((x <= y) && (x != y)); }

inline friend bool operator >(const Set & x, const Set & y) {

return y < x;

}

friend ostream & operator <<(ostream & os, const Set & s) {

if (s.Empty()) {

os << "{}"; return os; }

for (int i = 0; i < __SETSIZE; ++i) { if (s.Data[i]) os << ToAlpha(i); } return os; }

inline void Print(string msg = "") { cout << msg;

if (Empty()) {

cout << "{}"; return; }

for (int i = 0; i < __SETSIZE; ++i) { if (Data[i]) cout << ToAlpha(i); } } }; void TestSet() { Set x, y; x = "AB"; y = "BDE"; cout << "\n x = " << x; cout << "\n y = " << y; cout << "\n x >= y ? " << (x >= y); cout << endl;

for (int i = 0; i < 26; ++i) { cout << x[i];

}

cout << endl;

for (int i = 0; i < 26; ++i) {

if (y[i] != NULL) cout << y[i]; }

cout << endl;

for (int i = 0; i < 26; ++i) { cout << z[i];

} }

Main() { TestSet(); cout << "\n T H E E N D ."; return 0; } Kết quả thực hiện Màn hình

3.3 Thiết kế lớp lược đồ quan hệ RSC

3.3.1 Các thuôc tính của lớp lược đồ quan hệ RSC

Cú pháp Set Attr; int FDNum; FD * F; int Cap; Set Key;

Ý nghĩa: Khai báo các thuộc tính, phụ thuộc hàm

3.3.2 Các phương thức của lớp lược đồ quan hề RSC

Tạo tử (constructor)

Cú pháp

inline RSC() {Reset();}

inline RSC(const RSC &r) { Reset();

Copy(r); }

Cú pháp ~RSC() { if (F != NULL) { delete [] F; F = NULL; } }

Ý nghĩa: Xóa và thu hồi vùng nhớ đã cấp phát cho lớp lược đồ quan hề RSC

Cấp phát vùng chứa tên phần tử của lớp lược đồ quan hệ RSC

Cú pháp

inline void Renew()

Ý nghĩa: Cấp phát vùng nhớ đủ chứa size phần tử cho tập nền. Vùng nhớ này để lưu trữ danh sách (tên) các phần tử của tập nền.

Trả về vùng chứa phần tử của lớp lược đồ quan hệ RSC

Cú pháp void Reset() { FDNum = 0; Cap = 0; F = NULL; Attr.Reset(); Key.Reset(); }

Ý nghĩa: Gán độ thuộc 0 cho mọi phần tử của lớp lược đồ quan hệ RSC

Toán tử gán

Cú pháp

void Copy(const RSC & r) { Attr = r.Attr;

FDNum = r.FDNum; // so PTH Cap = r.Cap; // Capacity Key = r.Key; delete [] F; if (r.F == NULL) F = NULL; else { F = new FD[Cap];

for(int i = 0; i < FDNum; ++i)

F[i] = r.F[i];

}

Mở rộng vùng chứa lớp lược đồ quan hệ RSC

Cú pháp

void Extend() {

int newCap = Cap + __UNIT; FD *g = new FD[newCap];

for(int i = 0; i < FDNum; ++i) g[i] = F[i];

Cap = newCap; delete [] F; F = g;

}

Ý nghĩa: Mở rộng vùng chứa lớp lược đồ quan hệ RSC

Chèn mới

Cú pháp

void Ins(const Set & ls, const Set & rs) { if (F == NULL) { Cap = __UNIT; F = new FD[Cap]; F[0].Put(ls,rs); FDNum = 1; Attr = F[0].GetLR(); return; }

if (FDNum == Cap) Extend();

F[FDNum].Put(ls,rs); ++FDNum;

Attr += (ls + rs); }

void Ins(string ls, string rs) {Ins(Set(ls), Set(rs));}

Cú pháp

Set Closure(const Set & x, int k = -1) {

bitset<1000> mark; // danh dau cac FD da dung Set y = x;

int used = 0; while(true) {

used = 0;

for (int i = 0; i < FDNum; ++i) { if (i == k) continue;

if (mark[i] == 0) {

y += F[i].GetRS(); mark[i] = 1; ++used; } } } if (used == 0) break; } return y; }

Ý nghĩa: Tạo phụ thuộc hàm của lược đồ quan hệ RSC

Cú pháp

Set FindKey() { Set k = Attr;

for (char c = 'A'; c <= 'Z'; ++c) { if (k.Has(c)) { k.Del(c); if (!(Closure(k).Has(c))) k.Ins(c); } } return k; }

inline Set SetKey() { Key = FindKey(); return Key;

}

inline void NewKey(const Set &k) { Key = k;

}

inline void NewKey(const string s) { Key = Set(s);

}

Ý nghĩa: Tìm khóa cho lược đồ quan hệ RSC

Ví dụ:

Cho lược đồ quan hệ VẬN CHUYỂN (số_vận_đơn, kho_hàng, nơi_đến, khoảng_cách)

Ta mã hóa đặt: số_vận_đơn = A, kho_hàng = B, nơi_đến = C, khoảng_cách = D. Số thuộc tính U=ABCD

Với các tập phụ thuộc hàm: số_vận_chuyển xác định kho_hàng, nơi_đến, khoảng_cách. Kho_hàng, nơi_đến xác định khoảng_cách.

F={A BCD, BC D}

Mở file”K.txt” rồi ghi vào file, ta thực hiện tìm khóa K của lược đồ quan hệ VẬN

CHUYỂN. Cuối cùng ta ghi vào output tổng số lượng khóa của lược đồ quan hệ VẬN CHUYỂN.

Muốn tìm khóa của LĐQH:

Cho LĐQH p = (U,F). Tập thuộc tính K  U được gọi là khoá của LĐ p nếu

(i) K += U

(ii)  A  K: (K  {A})+ U

Hai điều kiện trên tương đương với (i') K  U

(ii')  A  K: (K  {A}) ! U

Nếu K thoả điều kiện (i) thì K được gọi là một siêu khoá.

Thuộc tính A U được gọi là thuộc tính khoá (nguyên thuỷ hoặc cơ sở) nếu A có trong một khoá nào đấy. A được gọi là thuộc tính không khoá (phi

nguyên thuỷ hoặc thứ cấp) nếu A không có trong bất kỳ khoá nào. Cho LĐQH

(U,F), ta kí hiệu UK là tập các thuộc tính khóa và Uo là tập các thuộc tính không

khóa. ******************************************* Chương trình ******************************************* #include <iostream> #include <fstream> #include <bitset> using namespace std;

const int __SETSIZE = 26; const int __UNIT = 16;

typedef bitset<__SETSIZE> BS;

class RSC { protected:

Set Attr; // Attribute Set

int FDNum; // number of functional dependencies FD * F; // functional dependencies

int Cap; // Capacity Set Key; void Reset() { FDNum = 0; Cap = 0; F = NULL; Attr.Reset(); Key.Reset(); } Set FindKey() { Set k = Attr;

for (char c = 'A'; c <= 'Z'; ++c) { if (k.Has(c)) { k.Del(c); if (!(Closure(k).Has(c))) k.Ins(c); } } return k; }

inline Set SetKey() {

Key = FindKey(); return Key;

}

inline void NewKey(const Set &k) { Key = k;

}

inline void NewKey(const string s) { Key = Set(s);

}

inline bool IsSuperkey(const Set &x) {

if (!(x <= Attr)) return false; if (Key <= x) return true;

return Attr <= Closure(x); }

inline bool IsSuperkey(const string s) {

return IsSuperkey(Set(s)); }

if (!IsSuperkey(x)) return false; Set k = x;

for (char c ='A'; c <= 'Z'; ++c) { if (k.IsIn(c)) { k.Del(c); if (Closure(k).IsIn(c)) return false; k.Ins(c); } } return true; }

inline bool IsKey(const string s) { return IsKey(Set(s)); } void TestRSC() { RSC r; r.Read("K.txt"); r.Show("\n r: ");

cout << "\n Key : " << r.GetKey();

} main() { TestRSC(); cout << "\n T H E E N D ."; return 0; } Kết quả ra màn hình

Nội dung file “K.txt

Ví dụ: Chương trình DemoSC.cpp thực hiện các thao tác như sau: Cho một lược đồ quan hê ĐƠN HÀNG (số_đơn, mã_KH, tên_KH, địa_chỉ_KH, ngày_đặt,

mã_hàng, tên_hàng, đơn_vị, mô_tả, số_lượng). Ta mã hóa đặt: số_đơn = A,

mã_KH = B, tên_KH = C, địa_chỉ_KH =D, ngày_đặt = E, mã_hàng = F,

tên_hàng = G, đơn_vị =H, mô_tả =I, số_lượng = J Số thuộc tính U=ABCDEFGHIJ

Tập phụ thuộc hàm xác định: mã_KH xác định tên_KH, địa_chỉ_KH; mã_hàng xác định tên_hàng, đơn_vị, mô_tả; số_đơn xác định mã_KH, ngày_đặt, mã_hàng. Ta viết tắt như sau F={B  CD; F GHI; AF J; A BEF}. Mở file “K.txt” rồi ghi vào file, ta hiển thị số tập thuộc tính, tìm khóa K của lược đồ quan hệ ĐƠN HÀNG. Tìm tập phụ thuộc hàm của AB và tập phụ thuộc F, kiểm tra E có phải là khóa của lược đồ quan hệ không. Cuối cùng ta ghi vào output file của lược đồ quan hệ ĐƠN HÀNG.

Chương trình /******************************************* DemoSC.cpp *************************************************/ #include <iostream> #include <fstream> #include <bitset> using namespace std;

const int __SETSIZE = 26; const int __UNIT = 16;

typedef bitset<__SETSIZE> BS;

class RSC { protected:

Set Attr; // Attribute Set

int FDNum; // number of functional dependencies FD * F; // functional dependencies

int Cap; // Capacity Set Key; void Reset() { FDNum = 0; Cap = 0; F = NULL; Attr.Reset(); Key.Reset(); }

public:

inline RSC() {Reset();}

inline RSC(const RSC &r) { Reset(); Copy(r); } ~RSC() { if (F != NULL) { delete [] F; F = NULL; } }

inline void Renew() { Reset(); if (F != NULL) delete [] F; F = NULL; } // Renew private:

void Copy(const RSC & r) {

Attr = r.Attr; // Tap thuoc tinh

FDNum = r.FDNum; // so PTH

Cap = r.Cap; // Capacity

Key = r.Key; delete [] F; if (r.F == NULL) F = NULL; else { F = new FD[Cap];

for(int i = 0; i < FDNum; ++i)

F[i] = r.F[i];

}

}

public:

inline void operator =(const RSC & r) {Copy(r);}

inline int GetFDNum() const {return FDNum;}

inline Set GetKey() const {return Key;}

void Extend() {

int newCap = Cap + __UNIT; FD *g = new FD[newCap];

for(int i = 0; i < FDNum; ++i) g[i] = F[i]; Cap = newCap; delete [] F; F = g; }

void Ins(const Set & ls, const Set & rs) { if (F == NULL) { Cap = __UNIT; F = new FD[Cap]; F[0].Put(ls,rs); FDNum = 1; Attr = F[0].GetLR(); return; }

if (FDNum == Cap) Extend();

F[FDNum].Put(ls,rs); ++FDNum;

Attr += (ls + rs); }

void Ins(string ls, string rs) {Ins(Set(ls), Set(rs));}

void Norm() { int j = -1; int k;

for (int i = 0; i < FDNum; ++i) {

if (F[i].GetRS().Empty()) continue; ++j; F[j] = F[i]; for (int k = 0; k < j; ++k) { if (F[k].GetLS() == F[i].GetLS()) { F[k].AddRS(F[i].GetRS()); --j; break; } } } FDNum = j+1; Attr.Reset();

for (int i = 0; i < FDNum; ++i) { Attr += F[i].GetLR();

} }

bitset<1000> mark; // danh dau cac FD da dung Set y = x;

int used = 0; while(true) { used = 0;

for (int i = 0; i < FDNum; ++i) { if (i == k) continue; if (mark[i] == 0) { if (F[i].GetLS() <= y) { y += F[i].GetRS(); mark[i] = 1; ++used; } } } if (used == 0) break; } return y; }

inline Set Closure(const string s, int k = -1) { return Closure(Set(s),k);

}

Set FindKey() { Set k = Attr;

for (char c = 'A'; c <= 'Z'; ++c) { if (k.Has(c)) { k.Del(c); if (!(Closure(k).Has(c))) k.Ins(c); } } return k; }

inline Set SetKey() { Key = FindKey(); return Key;

}

inline void NewKey(const Set &k) { Key = k;

}

inline void NewKey(const string s) { Key = Set(s);

}

if (!(x <= Attr)) return false; if (Key <= x) return true;

return Attr <= Closure(x); }

inline bool IsSuperkey(const string s) {

return IsSuperkey(Set(s)); }

bool IsKey(const Set &x) { if (!IsSuperkey(x))

return false; Set k = x;

for (char c ='A'; c <= 'Z'; ++c) { if (k.IsIn(c)) { k.Del(c); if (Closure(k).IsIn(c)) return false; k.Ins(c); } } return true; }

inline bool IsKey(const string s) { return IsKey(Set(s));

}

bool Derive(const FD & g, int k = -1) {

return (Closure(g.GetLS(),k) >= g.GetRS()); }

bool Derive(string ls, string rs, int k = -1) { return Derive(FD(ls,rs),k);

} // Derive

void NonRedundant() {

for(int i = FDNum-1; i >= 0; --i) { if (Derive(F[i],i)) { if (FDNum-1 > i) { F[i] = F[FDNum-1]; } --FDNum; } } }

void Read(const char * fn) { ifstream f(fn);

cerr << "\n Unable open in file " << fn; return; } Reset(); cout << "\n Reading ... "; string s; string ls, rs; int i; while(true) { getline(f,s); cout << "\n " << s; if (s[0] == '.') break; // Left Side ls = "";

for (i = 0; s[i] != '-'; ++i) { if (IsAlpha(s[i]))

ls += s[i]; }

rs = "";

for (i = i+1; i < s.length(); ++i) { if (IsAlpha(s[i])) rs += s[i]; } Ins(ls,rs); // New FD ls -> rs } f.close(); Norm(); Show("\n Read: "); NonRedundant(); SetKey(); }

inline bool IsBCNF() {

for (int i = 0; i < FDNum; ++i) { if (!IsSuperkey(F[i].GetLS())) return false; } return true; } void Print(string msg = "") { cout << msg;

Attr.Print("\n Attribute Set: "); Key.Print("\n Key: ");

cout << "\n Functional Dependencies: "; for (int i = 0; i < FDNum; ++i) {

cout << "\n " << i << ". "; F[i].Print();

}

friend ostream & operator <<(ostream & os, const RSC & s) { os << "\n Attribute Set: ";

os << s.Attr;

os << "\n Functional Dependencies: "; for (int i = 0; i < s.FDNum; ++i)

os << "\n " << i << ". " << s.F[i]; return os;

}

void Show(string msg = "") {

Một phần của tài liệu (LUẬN văn THẠC sĩ) lược đồ cơ sở dữ liệu chuẩn hóa (Trang 37)

Tải bản đầy đủ (PDF)

(73 trang)