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]);

}

}

- 234 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

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[];

- 235 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

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))

- 236 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

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");

- 237 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

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: ";

- 238 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

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 ả

Nga (N )ữ

Tu n (Nam)

- 239 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

ườ

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: ả ữ ệ ệ

Tao Than g 1 Tao Mai 0 Cuoi Than g Mai Sinh Mai Nga 0 Sinh Mai

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));

- 240 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

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;

- 241 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

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;

- 242 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

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();

- 243 -

Phô lôc 3: Bµi to¸n quan hÖ gia ®×nh

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

- 244 -