Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
Ph l c 3 ụ ụ
Bài toán quan h gia đình ệ
ệ ụ ự ươ
Trong m c này, ta s xây d ng ch c phân tích ầ ủ
ồ ch ở ươ ể
ng th c sinh, c
ươ ỉ ự ộ b ng l p ả ằ ươ ệ ữ
ứ ỉ ả ướ ữ ư ậ ự ể
ớ
ớ i. L p con ng l p Con ng ườ ẽ ứ ườ ớ ộ
ư ể i. Nh v y có s phân chia t p đ i t Nam và Nữ. Rõ ràng, hai l p này ph i k i s ch a các thu c tính và ph ề ữ ể
ừ ừ ớ ớ
i, l p Nam có thêm thu c tính ng th c ứ Sinh con. Thi ườ ớ ươ ữ ầ ủ ớ
ng trình cho bài toán quan h gia đình đã ẽ đ ng m t. Theo nh s phân tích ban đ u c a bài toán, ta có ư ự ượ ớ Con ng m t t p các cá th và mô t iườ bao g m các thu c tính tên, ộ ộ ậ anh em, cha m , ... và các ph i, ... Nh ng ta có nh n xét r ng ằ ậ ứ ẹ c trên nh ng cá th là n và ph ng th c sinh ch th c hi n đ ph ứ ng th c ươ ượ c i ch x y ra cho hai cá th khác gi ng ậ ố ượ ớ ướ ả ế c a bài toán thành hai l p khác nhau là ủ ứ th a t ng th c ươ ừ ừ ớ ầ ượ ế chung, dù cá th là Nam hay N cũng đ u ph i có. Ngoài cá thành ph n đ c k ả Vợ, l p N có thêm thu c th a t ộ l p Con ng ộ t k các l p ban đ u c a bài toán tính Ch ngồ và ph ế ế i đây. nh hình d ướ ư
iườ
Con ng Tên Cha mẹ Anh em Con cái
ớ
Gi i tính iướ
C
Nam Vợ
Nữ Ch ngồ
Sinh con
ế
ế ơ ộ
ủ
ớ
Thi t k s b các l p c a bài toán
Ph i tính ộ ươ ể
ạ ớ ữ
ươ
ể ả ờ ườ ả c đó là Nam hay N . Câu tr l ả ờ l p k th a Nam và N . Ph ươ ở ớ l p Nam tr k t qu là 1 còn dùng đ tr l ứ Gi ng th c ớ ế ả ế i đ i tính không th tr l ể ả ờ ượ i tính ng th c Gi ứ ớ ả ả ế ữ ả ế ữ ả
ậ t c ế ướ ầ ở ồ
N u là Nam k t qu là 1 còn là k t qu là 0. Rõ ràng t ế th c Gi ớ ứ i các ph đ nh t ạ ị Gi i tính ở ớ ớ c kĩ thu t này, ta dùng kĩ thu t hàm o trong LTHĐT. L p lu n t hi n đ ệ ượ t cho ph ự ươ i v . Đ tr l c ướ ợ ể ả ờ i xem m t cá th đó là Nam hay N . ữ i ph ươ ng i l p Con ng i ch xác ỉ ng th c ứ ế ừ l p N tr k t qu là 0. Đ th c ể ự ở ớ ậ ươ ng ả ậ ậ i ch ng hay ứ C iướ , b i vì ph ng th c ứ ươ ầ i cho các câu h i v m i quan h gia đình chúng ta cũng c n ng th c này c n bi ệ ỏ ề ố
- 230 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
i các câu h i nh ả ư Là Anh, Là Ông(X), ỏ
ph i xây nh ng ph v.v... Hình d ươ i đây thi ữ ướ ng th c đ tr l ứ ể ả ờ t k các l p c a bài toán. ớ ủ ế ế
iườ
Con ng Tên Cha mẹ Anh em Con cái
oả >
ướ
Gi i tính < oả >
ớ C
i < Là Anh Là Ông . . . .
Nam Vợ
Nữ Ch ngồ
Gi i tính iướ
ớ C
Sinh con Gi i tính iướ
ớ C
ủ
ế
ế
ớ Thi t k các l p c a bài toán
i ngôn ng C++ có b sung thêm m t s ộ ố ổ
thu c tính và ph Sau đây là th hi n c a các l p d ể ệ ủ ứ ươ ộ ớ ướ ng th c ph c v vi c cài đ t l p. ụ ụ ệ ữ ặ ớ
class Nguoi {
friend class Nam;
friend class Nu;
char Ten[25];
Nam *Bo;
Nu *Me;
Nguoi *AnhChi[10], *CacEm[10], *CacCon[10];
int SoAnhChi, SoEm, SoCon;
- 231 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
Nguoi(char *ten, Nam *bo, Nu *me) :
Bo(bo), Me(me), SoAnhChi(0), SoEm(0), SoCon(0)
{
strcpy(Ten, ten);
}
void ThemAnhChi(Nguoi* nguoi)
{
AnhChi[SoAnhChi++] = nguoi;
}
void ThemEm(Nguoi* nguoi)
{
CacEm[SoEm++] = nguoi;
}
void ThemCon(Nguoi* nguoi)
{
CacCon[SoCon++] = nguoi;
}
public:
// 1 la Nam, 0 la Nu
virtual int GioiTinh()=0;
virtual int Cuoi(Nguoi*)=0;
int LaCha(Nguoi *);
int LaMe(Nguoi *);
int LaCon(Nguoi *);
int LaAnh(Nguoi *);
int LaChi(Nguoi *);
int LaEm(Nguoi *);
int LaCo(Nguoi *);
int LaDi(Nguoi *);
int LaChu(Nguoi *);
int LaCau(Nguoi *);
- 232 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
int LaMo(Nguoi *);
int LaBac(Nguoi *);
int LaOngNoi(Nguoi *);
int LaBaNoi(Nguoi *);
int LaOngNgoai(Nguoi *);
int LaBaNgoai(Nguoi *);
int LaAnhHo(Nguoi *);
int LaChiHo(Nguoi *);
int LaEmHo(Nguoi *);
virtual int LaVo(Nguoi*)=0;
virtual int LaChong(Nguoi*)=0;
};
class Nam : public Nguoi
{
Nu *Vo;
int LaVo(Nguoi *) { return 0; }
public:
Nam(char *ten, Nam *bo=0, Nu *me=0) :
Nguoi(ten, bo, me), Vo(0) {}
int GioiTinh() { return 1; }
int Cuoi(Nguoi *vo);
int LaChong(Nguoi * nguoi);
};
class Nu : public Nguoi
{
Nam *Chong;
int LaChong(Nguoi *) { return 0; }
public:
Nu(char *ten, Nam *bo=0, Nu *me=0):
Nguoi(ten, bo, me), Chong(0) {}
- 233 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
int GioiTinh() { return 0; }
int Cuoi(Nguoi *chong);
void SinhCon(char* ten, int gioitinh);
int LaVo(Nguoi * nguoi);
};
i ch th c hi n đ i v i cá th ch a l p gia đình. Trong ỉ ự ố ớ ư ậ ể
Ph ng h p đã l p gia đình thì nó s tr ra 0. tr ng th c c ươ ợ ứ ướ ậ ệ ẽ ả ườ
int Nam::Cuoi(Nguoi *vo)
{
if (Vo||vo->GioiTinh()) return 0;
Vo = (Nu*)vo;
Vo->Cuoi(this);
return 1;
}
int Nu::Cuoi(Nguoi *chong)
{
if (Chong||chong->GioiTinh()==0) return 0;
Chong = (Nam*)chong;
Chong->Cuoi(this);
return 1;
}
void Nu::SinhCon(char *ten, int gioitinh)
{
Nguoi* nguoi = TaoNguoi(ten, gioitinh, Chong, this);
ThemCon(nguoi);
if (Chong) Chong->ThemCon(nguoi);
for (int i=0; i { CacCon[i]->ThemEm(nguoi); nguoi->ThemAnhChi(CacCon[i]); } } Trong ph ứ ươ ể ạ
ớ ạ ố ượ ớ i tính. Đ i t
ố ượ ồ ể ệ
ng th c sinh con đã dùng hàm TaoNguoi đ t o ra m t th hi n
ộ
ng m i t o ra s đ
c gia
ẽ ượ
t v hàm
ệ
ế ề
ng thì các m i quan h gia
ệ
ố ẽ ậ c a l p Nam hay Nu ph thu c vào gi
ủ ớ
ụ
nh p vào c ng đ ng và đ
ộ
ậ
này chúng ta s bàn lu n sau. Sau khi đã có đ i t
đình cha, m , con cái, anh, ch , em ph i đ ộ
c xem xét các m i quan h sau này, chi ti
ố ượ
c xác l p.
ậ ả ượ ẹ ị Th c hi n cài đ t các ph ỏ ặ ươ l
ả ờ ố ệ
ố ớ ộ ơ ệ ở ề ươ ể ả
ồ
ể ự ư
ộ
ộ ủ
ủ
ả ư ụ ụ ồ ụ ặ ả
ủ ớ
ng là Nam ho c N ph thu c gi
ữ
ng m i t o ra s đ
c thêm vào c ng đ ng. Ph
ộ
ẽ ượ
ng trong c ng đ ng có tên nh tên đ a vào, n u không tìm th y tr
ồ ồ
ư ư ộ i câu h i quan h c a l p Con
ng th c tr
ệ ủ ớ
ự
ứ
ấ
i. Đ i v i các m i quan h g n nh LaAnh, LaCha thì vi c ki m tra r t
ng
ể
ệ
ư
ệ ầ
ườ
ng. Nh ng đ i
đ n gi n thông qua các thu c tính Bo, Me, AnhChi,... c a đ i t
ố
ả
ư
ủ ố ượ
ơ
v i m i quan h xa h n chút ít nh LaOngNoi, LaCo, LaChu,... thì tr nên khó
ố
ớ
ng pháp ki m tra đ n gi n theo mô
khăn h n nhi u. Chúng ta dùng m t ph
ơ
ơ
i
hình toán h c. Ví d , A là ông n i c a B khi và ch khi trong c ng đ ng t n t
ồ ạ
ộ
ọ
ụ
ỉ
ng X mà A là cha c a X và X là cha c a B. Nh v y đ th c hi n
m t đ i t
ệ
ư ậ
ủ
ộ ố ượ
ộ
ng trong c ng
c ki m tra này thì c n ph i l u đ
đ
c toàn b các đ i t
ượ
ầ
ố ượ
ộ
ể
ượ
ng trình dùng m t m ng tĩnh các con
đ ng đ ph c v tìm ki m X. Trong ch
ế
ồ
ộ
ể
ả
ươ
i này. M ng này đ
i đ qu n lý c ng đ ng ng
tr t
ượ
c
ng Con ng
i đ i t
ả
ộ
ườ ể
ỏ ớ ố ượ
ườ
ứ TaoNguoi
ng th c
khai báo nh m t thành ph n tĩnh c a l p Con ng
i. Ph
ươ
ườ
ầ
ư ộ
i tính truy n vào. Đ i
s t o m t đ i t
ố
ộ
ộ ố ượ
ề
ẽ ạ
ớ
ứ TimNguoi tìm đ iố
ng th c
t
ươ
ớ ạ
ượ
t
ả ề
v
ế
ấ
ượ
NULL. D i đây là m t s b sung cho l p Con ng
i.
ườ
ộ ố ổ ướ ớ class Nguoi { . . . static Nguoi* NhanDan[100]; static int SoDan; public: . . . static int LaySoDan() { return SoDan; } static Nguoi* ThemDan(Nguoi* nguoi) { return NhanDan[SoDan++] = nguoi; } static Nguoi* TaoNguoi(char*, int, Nam *bo=0, Nu *me=0); static Nguoi* TimNguoi(char* ten); }; Nguoi* Nguoi::NhanDan[]; int Nguoi::SoDan = 0; Nguoi* Nguoi::TaoNguoi(char* ten, int gioitinh, Nam *bo, Nu *me) { return gioitinh ? ThemDan(new Nam(ten, bo, me)) : ThemDan(new Nu(ten, bo, me)); } Nguoi* Nguoi::TimNguoi(char* ten) { for (int i=0; i if (strcmp(ten, NhanDan[i]->LayTen())==0) return NhanDan[i]; return 0; } Sau khi đã t ch c đ ổ ứ ượ ữ ệ ư ể ườ
ố ượ ể
ể ọ c d li u l u tr con ng
ữ
i đây. A là đ i t
ng tìm ki m NhanDan[i] (dùng vòng i chúng ta có th xây d ng
ự
ng g i hàm ki m tra, B là
for để ệ ư ướ
ố ượ ế các hàm ki m tra quan h nh d
đ i t
ng truy n vào, X là đ i t
ề
ố ượ
duy t).ệ int Nguoi::LaOngNoi(Nguoi *nguoi) { if (GioiTinh()==0) return 0; for (int i=0; i if (LaCha(NhanDan[i])&&NhanDan[i]->LaCha(nguoi)) return 1; return 0; } int Nguoi::LaBaNoi(Nguoi *nguoi) { if (GioiTinh()) return 0; for (int i=0; i if (LaMe(NhanDan[i])&&NhanDan[i]->LaCha(nguoi)) return 1; return 0; } M c đích c a ch ng trình là sau khi đã có d li u ph i tr l i đ ụ ươ ả ả ờ ượ i vào. Sau khi ng ữ ệ
ườ ử ụ ư ẽ ư ồ ố ượ c câu
i s d ng đ a tên vào chúng
ư
ng đó trong c ng đ ng. N u tìm th y thì g i hàm đ a ra thông
ấ
i đây th c hi n
ệ
ự
ạ ổ
i đ i
t c không tho mãn thì l ướ
ả c l ủ
h i quan h khi đ a tên hai ng
ườ
ệ
ỏ
ta s tìm đ i t
ọ
ộ
ế
ố ượ
ng v a tìm th y. Trong hàm d
báo quan h c a hai đ i t
ấ
ừ
ệ ủ
b ng cách ki m tra các quan h b trên n u t
ằ
ệ ề
ế ấ ả
ể
ng th c đ ki m tra.
ng g i ph
i đ i t
ng
ứ ể ể
ọ
ượ ạ ố ượ ươ char qh[256]; ng // đ a ra thông báo v quan h c a 2 đ i t
ề ệ ủ ố ượ ư char* QuanHe(Nguoi* A, Nguoi* B) { for (int i=1; i<=2; i++) { strcpy(qh, A->LayTen()); strcat(qh, " va "); strcat(qh, B->LayTen()); strcat(qh, " co quan he "); if (A->LaOngNoi(B)) return strcat(qh, "ong chau noi"); if (A->LaBaNoi(B)) return strcat(qh, "ba chau noi"); if (A->LaOngNgoai(B)) return strcat(qh, "ong chau ngoai"); if (A->LaBaNgoai(B)) return strcat(qh, "ba chau ngoai"); if (A->LaCha(B)) return strcat(qh, "cha con"); if (A->LaMe(B)) return strcat(qh, "me con"); if (A->LaCo(B)) return strcat(qh, "co chau"); if (A->LaDi(B)) return strcat(qh, "di chau"); if (A->LaChu(B)) return strcat(qh, "chu chau"); if (A->LaBac(B)) return strcat(qh, "bac chau"); if (A->LaAnh(B)) return strcat(qh, "anh em"); if (A->LaChi(B)) return strcat(qh, "chi em"); if (A->LaAnhHo(B)) return strcat(qh, "anh em ho"); if (A->LaChiHo(B)) return strcat(qh, "chi em ho"); if (A->LaVo(B)) return strcat(qh, "vo chong"); Nguoi* temp = A; A = B; B = temp; } strcpy(qh, A->LayTen()); strcat(qh, " va "); strcat(qh, B->LayTen()); return strcat(qh, " khong co quan he gia dinh"); } ng có tên nh p vào t bàn phím // tìm quan h c a hai đ i t
ẹ ủ ố ượ ậ ừ void TimQuanHe() { clrscr(); char ten1[25]; cout << "Ten nguoi thu nhat: "; gets(ten1); Nguoi *A = Nguoi::TimNguoi(ten1); if (A==0) { cout << "Khong co nguoi ten " << ten1 << endl; getch(); return; } char ten2[25]; cout << "Ten nguoi thu hai: "; gets(ten2); Nguoi *B = Nguoi::TimNguoi(ten2); if (B==0) { cout << "Khong co nguoi ten " << ten2 << endl; getch(); return; } cout << QuanHe(A, B) << endl; getch(); } t k nh p d li u cho ch Đ đ n gi n trong vi c thi ậ ả ệ ữ ệ ươ ng pháp nh p d li u t t p. Vi c hình thành con ng ế ế
ậ ữ ệ ừ ệ ườ ệ
ự ệ ườ i, Sinh con c a ng ườ ủ ể ng trình, chúng ta
ố
i và các m i
i, Đám
ể
ả
ra thích h p
ợ
cho m t quan h gia ể ơ
ươ
ệ ủ
i c a hai ng
ề
ợ ộ
ạ
i ph n . Do v y t p d li u ph i th
ậ ệ
các s ki n t
ự ệ ỏ
ộ
ả ườ
ả
ộ ệ ả
ả ướ ệ ắ Th ng (Nam) Mai (N )ữ dùng ph
quan h c a chúng là thông qua các s ki n chính: T o m t con ng
c
ướ ủ
ữ ệ
hi n đ
ượ
ệ
trong tr
ườ
đình đ n gi n.
ơ ụ ữ
c đi u này. Dùng t p văn b n đ mô t
ệ
ng h p này. D i đây là m t t p văn b n mô t
ả ạ ườ T o ng ắ
i tên Th ng là nam ạ ườ ữ T o ng i tên Mai là n ắ ướ Th ng c i Mai Mai sinh con gái tên là Nga Mai sinh con trai tên là
Tu nấ T p văn b n d li u: ả ữ ệ ệ Hàm nh p d li u t t p văn b n. ậ ữ ệ ừ ệ ả void NhapDuLieu() { clrscr(); char s[80]; cout << "Ten tep nhap du lieu: "; cin >> s; ifstream input(s, ios::in|ios::nocreate); input.seekg(0L, ios::end ); if ( input.tellg() < 0) { cout << "Loi mo tep ! \n"; getch(); return; } input.seekg(0L, ios::beg); cout << "Dang nhap du lieu........\n"; int dong = 1; while (1) { input.getline(s, sizeof(s)); if (input.gcount()==0) break; if (strcmp(s, "")==0) { dong++; continue; } if (strcmp(s, "Tao")==0) { char ten[25]; input.getline(ten, sizeof(ten)); if (strcmp(ten, "")) { int gt; input >> gt; cout << "Tao nguoi ten " << ten << endl; if (Nguoi::TimNguoi(ten)) cout << "Da co nguoi ten la " << ten << endl; else Nguoi::TaoNguoi(ten, gt); dong += 2; continue; } } if (strcmp(s, "Cuoi")==0) { char ten1[25]; input.getline(ten1, sizeof(ten1)); char ten2[25]; input.getline(ten2, sizeof(ten2)); Nguoi* A = Nguoi::TimNguoi(ten1); Nguoi* B = Nguoi::TimNguoi(ten2); cout << "Cuoi " << ten1 << " va "<< ten2 << endl; if (A==0) cout << "Khong co nguoi ten " << ten1 << endl; if (B==0) cout << "Khong co nguoi ten " << ten2 << endl; if (A&&B&&A->Cuoi(B)==0) cout << "Khong cuoi duoc\n"; dong += 2; continue; } if (strcmp(s, "Sinh")==0) { char ten1[25]; input.getline(ten1, sizeof(ten1)); char ten2[25]; input.getline(ten2, sizeof(ten2)); if (strcmp(ten2, "")) { cout << ten1 << " sinh con "<< ten2 << endl; Nguoi* A = Nguoi::TimNguoi(ten1); if (A==0) cout << "Khong co nguoi ten " << ten1 << endl; int gt; input >> gt; if (Nguoi::TimNguoi(ten2)) cout << "Da co nguoi ten la " << ten2 << endl; else { if ( A ) if ( A->GioiTinh() ) cout << ten1 <<" la nam khong sinh con duoc\n"; else ((Nu*)A)->SinhCon(ten2, gt); } dong += 3; continue; } } cout << "Loi o dong thu " << dong << endl; break; } cout << "Ket thuc nhap.\n"; getch(); } Vi t thêm menu cho ch ế ươ ng trình có d ng nh sau:
ạ ư Lua chon cong viec theo so 1. Nhap du lieu 2. Tim quan he 3. Ket thuc void Menu() { clrscr(); cout << "\n\n Lua chon cong viec theo so\n\n"; cout << " 1. Nhap du lieu\n"; cout << " 2. Tim quan he\n"; cout << " 3. Ket thuc\n"; } void main(){ int i; Menu(); do { i = getch(); switch (i) { case '1': Nguoi::XoaDuLieu(); NhapDuLieu(); Menu(); break; case '2': TimQuanHe(); Menu(); } }while (i!='3'); Nguoi::XoaDuLieu(); } t p d li u nh ta có trên ụ ươ ư ở và th c hi n tìm quan h màn hình s có d ng nh sau Ví d sau khi nh p d li u cho ch
ẽ
ự ậ ữ ệ
ệ ng trình t
ừ ệ ữ ệ
ư
ạ ệ Ten nguoi thu nhat: Thang Ten nguoi thu hai: Mai Mai va Thang co quan he vo chong- 234 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
- 235 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
- 236 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
- 237 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
- 238 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
ấ
Nga (N )ữ
Tu n (Nam)
- 239 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
Tao
Than
g
1
Tao
Mai
0
Cuoi
Than
g
Mai
Sinh
Mai
Nga
0
Sinh
Mai
- 240 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
- 241 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
- 242 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
- 243 -
Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh
- 244 -