Kiểu tậphợp I. Kiểu tậphợp Một tậphợp bao gồm một số đối tợng nào đó có cùng bản chất. TrongPascal điều đó có ngiã là mô tả cùng một kiểu, kiểu bày gọi là kiểu cơ bản. Kiểu cơ bản bắt buộc phải là một kiểu vô hớng hay đoạn con và không đợc là số thực. Các đối tợng này gọi là các phần tử của tập. Số phần tử cực đại cho phép trong Boland Pascal là 256. Để mô tả kiểu và khai báo biến tập hợp, ngời ta dùng từ khoá SET OF theo sau là kiểu cơ bản T (kiểu của các phần tử của tập) VD : TYPE Chu_Cai = SET OF CHAR; Chu_So = SET OF 0 9; VAR SO : CHU_SO; L : CHU_CAI; A : SET OF BYTE; II. Xác lập một tập Một tậphợp đợc xác định bằng cách liệt kê các phần tử của tập hợp, chúng cách nhau bằng dấu phẩy và đợc đặt giữa 2 dấu ngoặc vuông. VD : []; [3 5]; [3,4,5,8] hoặc [3 5,8]; ['A' 'C','Y','Z']; Bản thân các phần tử của tập cũng có thể cho bằng biến hoặc biểu thức VD : [X+Y, I*J, 3, 4] III. Các phép toán trên tập 1. Phép gán Với cách mô tả ở trên ta có thể gán VD : SO := [3 5]; L := ['A' 'E','Z']; A := [1 100,140 200]; L := []; Chúng ta không thể gán L := [3,5] vì kiểu cơ bản của chúng không tơng thích với nhau 2. Phép hợpHợp của 2 tập là một tập có các phần tử thuộc hai tập Đợc kí hiệu bằng dấu + VD : A := [3 5]; B := [4 6,10,123]; C := A+B; { Tập C sẽ là [3 6,10,123] } 3. Phép giao Giao của 2 tập là một tập có các phần tử nằm trong cả 2 tập Đợc kí hiệu bằng dấu * VD : Với VD trên ta gán C := A*B; Tập C sẽ là [4,5] 4. Phép hiệu Hiệu của 2 tập là tập các phần tử thuộc tập thứ nhất nhng khồn thuộc tập thứ hai. VD : Với VD trên ta gán C := A-B; Tập C sẽ là [3]; C := B-A; Tập C sẽ là [6,10,123]; 5. Phép thử "thuộc về" Là một phép thử để xem một biến, hay một giá trị có thuộc một tập nào đó không VD : Để thử biến ch có nằm trong câu trả lời Có bằng tiếng Việt hoặc bằng tiếng Anh là Yes không, bằng cách thông thờng ta viết IF(Ch='Y')or(Ch='y')or(Ch='C')or(Ch='c')THEN . Song ta có thể viết ngắn gọn với phép thử IN nh sau : IF Ch in['Y','y','C','c'] THEN 6. Các phép so sánh <>,=,<=,>= Hai tập đợc đem ra so sánh trớc hết phải có cùng kiểu cơ bản. Kết quả của phép so sánh là giá trị kiểu Boolean tức là : Đúng(TRUE) hoặc Sai(FALSE) Hai tập bằng nhau nếu chúng có phần tử nh nhau từng đôi một (không kể thứ tự sắp xếp trong 2 tập) Ngợc lại với phép = là phép so sánh khác nhau Phép so sánh <= sẽ có giá trị TRUE nếu tất cả phần tử tập thứ nhất đều thuộc tập thứ hai. Phép so sanh >= sẽ có giá trị TRUE nếu tất cả phần tử tập thứ hai đều thuộc tập thứ nhất Chú ý : TrongPascal không tồn tại phép so sánh <,>. Muốn so sánh lớn hơn hay nhỏ hơn ta dùng thủ thuật sau. IF (A<=B) AND (A<>B) THEN Writeln('A<B'); 7. Tổng kết các phép toán trên tập --------------------------------------------------- | Toán tử | Kí hiệu | Kiểu kết quả | ---------------------------------------------------- | Gán | := | SET OF . | | Hợp | + | SET OF . | | Giao | * | SET OF . | | Hiệu | - | SET OF . | | Thuộc về | IN | Boolean | | Bằng nhau | = | Boolean | | Khác nhau | <> | Boolean | | Bao hàm | <=,>= | Boolean | ---------------------------------------------------- Bài 1: { Viết chơng trình nhập từ bàn phím tập số A gồm các số nguyên trong khoảng 1 99 bằng cách nhập liên tục các số cho đến khi nhập số 0 thì kết thúc Tơng tự nhập tập B a. Tính giao của 2 tập. In ra màn hình b. Tính hợp của 2 tập. In ra màn hình} uses crt; var a,b,t:set of byte;{Tập a,b,t kiểu byte} i:byte;{i kiểu byte} begin clrscr;{Xoá màn hình} a:=[];b:=[];{Gán tập A và B bằng rỗng} writeln('Nhap tap A'); repeat readln(i);{Đọc i} if i>0 then a:=a+[i];{Nếu i>0 thì cộng i vào tập A} until i=0;{Cho đến khi i=0} writeln('Nhap tap B'); repeat readln(i);{Đọc I} if i>0 then b:=b+[i];{Nếu i>0 thì cộng i vào tập B} until i=0;{Cho đến khi i=0} Writeln('Giao'); t:=a*b;{Gán t bằng giao của A và B} for i:=1 to 99 do{Cho i chạy từ 1 đến 99} if i in t then write(i,' ');{Nếu i thuộc t thì xuất i} writeln; writeln('Hop'); t:=a+b;{Gán t bằng hợp của A và B} for i:=1 to 99 do{Cho i chạy từ 1 đến 99} if i in t then write(i,' ');{Nếu i thuộc t thì xuất i} readln; end. Bài 2: { Nhập N. Viết chơng trình tạo ra một tập số ngẫu nhiên trong khoảng từ 0 255 bằng cách : - Tạo ra ngẫu nhiên N số trong khoảng từ 0 255 Tính phần bù của tập đó VD : N=5 có 6 số : 0 1 2 3 6 2 thì tập đó là [0 3,6] phần bù của nó [4,5,7 255]} uses crt; var th:set of byte;{Tập th kiểu byte} i,a,n:integer;{i,a,n kiểu integer} begin clrscr;{Xoá màn hình} randomize; write('N = ');readln(n);{Đọc N} th:=[];{Gán tập th bằng rỗng} for i:=1 to n do{Cho i chạy từ 1 đến n} begin a:=random(256);{Gán a bằng số ngẫu nhiên trong khoảng 0 255} th:=th+[a];{Cộng a vào th} end; writeln('Phan bu'); th:=[0 255]-th;{Gán th bằng phần bù của nó} for i:=0 to 255 do{Cho i chạy từ 0 đến 255} if i in th then write(i,' ');{Nếu i thuộc th thì xuất i} readln; end. Bài 3: { Nhập số N (N<10). Tạo ra N tập số bằng cách với mỗi tập ta thực hiện : - Tạo ra 100 số ngẫu nhiên trong khoảng từ 0 255 (có thể trùng nhau) rồi cho vào tập đó a. In ra màn hình số phần tử của mỗi tập b. Xem tập nào là lớn nhất. In ra màn hình các số thuộc tập đó Hớng dẫn Nên viết hàm sopt(a)trả về số phần tử của tập a} uses crt; type taphop=set of byte; var th:array[1 10]of taphop;{Khai báo mảng th 10 phần tử kiểu taphop} i,j,a,max,n:byte;{i,j,a,max,n kiểu byte} function sopt(th:taphop):byte; var i,so:byte;{Khai báo i,so kiểu byte} begin so:=0;{Gán so bằng 0} for i:=0 to 255 do{Cho i chạy từ 0 đến 255} if i in th then inc(so);{Nếu i thuộc th thì tăng so} sopt:=so;{Gán sopt bằng so} end; begin clrscr;{Xoá màn hình} randomize; write('N = ');readln(n);{Đọc N} for i:=1 to n do th[i]:=[];{Gán th[1] th[n] bằng rỗng} for i:=1 to n do{Cho i chạy từ 1 đến n} for j:=1 to 100 do{Cho j chạy từ 1 đến 100} begin a:=random(256);{Gán a bằng số ngẫu nhiên trong khoảng 0 255} th[i]:=th[i]+[a];{Cộng a vào th[i]} end; max:=0;{Gán max bằng 0} for i:=1 to n do{Cho i chạy từ 1 đến n} begin writeln('So phan tu tap ',i,' : ',sopt(th[i]));{Xuất số phần tử tập i} if max<sopt(th[i])then{Nếu max nhỏ hơn số phần tử tập i} begin max:=sopt(th[i]);{Gán max bằng số phần tử tập i} a:=i;{Gán a bằng i} end; end; writeln('Tap ',a,' co so phan tu lon nhat');{Xuất tập lớn nhất} for i:=0 to 255 do{Cho i chạy từ 0 đến 255} if i in th[a] then write(i,' ');{Nếu i thuộc th[a] thì xuất i} readln; end. Bài 4: { Nhập N. Viết chơng trình in ra một hoán vị đầu tiên của N VD : N = 9 2 6 4 3 5 8 7 9 1 Hớng dẫn Gán th:=[] Thực hiện lấy N số bằng cách : - Lấy ngẫu nhiên số đó trong khoảng từ 1 N cho tới khi nó cha xuất hiện trong th - Cộng nó vào th} uses crt; var i,a,n:byte;{i,a,n kiểu byte} th:set of byte;{th kiểu byte} begin clrscr;{Xoá màn hình} write('N = ');readln(n);{Đọc N} th:=[];{Gán th bằng rỗng} for i:=1 to n do{Cho i chạy từ 1 đến n} begin repeat a:=random(n)+1 until not(a in th);{Gán a bằng số ngẫu nhiên từ 1 n cho đến khi a không thuộc th} write(a,' ');{Xuất a} th:=th+[a];{Cộng a vào th} end; readln; end. Bài 5: { Nhập N (N<=255). Tìm các số nguyên tố không vợt quá N bằng sàng Eratosthene. Hớng dẫn Gán th:=[2 N] Cho i chạy từ 2 đến trunc(sqrt(n)) Nếu i thuộc th thì xoá các bội của i trong khoảng i*i -> N ra khỏi th Các phần tử còn lại chính là các số nguyên tố} uses crt; var i,n:byte;{i,n kiểu byte} th:set of byte;{Tập th kiểu byte} a:integer;{a kiểu integer} begin clrscr;{Xoá màn hình} write('N = ');readln(n);{Đọc N} th:=[2 n];{Gán th bằng [2 n]} for i:=2 to trunc(sqrt(n))do{Cho i chạy từ 2 đến trunc(sqrt(n))} if i in th then{Nếu i thuộc th} begin a:=i*i;{Gán a bằng i*i} while a<=n do{Trong khi a<=n thì} begin th:=th-[a];{Loại a ra khỏi th} a:=a+i;{Tăng a thêm i đơn vị} end; end; for i:=2 to n do{Cho i chạy từ 1 đến n} if i in th then write(i:4);{Nếu i thuộc th thì xuất i} readln; end. Bài 6: { Nhập vào một chữ chuỗi kí tự. Xem có bao nhiêu loại kí tự xuất hiện trong đó VD : "abcdeDcB" Có 7 loại kí tự Hớng dẫn Khai báo th là tậphợp kiểu kí tự for i=1 -> length(s)do th:=th+[s[i]]; Sau đó for i:=0 to 255 do Nếu chr(i)xuất hiện trong TH thì tăng dem len 1} uses crt; var s:string;{Xâu S} i,dem:byte;{i,dem kiểu byte} th:set of char;{Tập th} begin clrscr;{Xoá màn hình} write('S = ');readln(s);{Đọc S} th:=[];{Gán th bằng rỗng} for i:=1 to length(s)do{Cho i chạy từ 1 đến chiều dài xâu S} th:=th+[s[i]];{Cộng s[i] vào th} dem:=0;{Gán dem bằng 0} for i:=0 to 255 do{Cho i chạy từ 0 đến 255} if chr(i)in th then inc(dem);{Nếu kí tự có mã là i có trong th thì tăng dem} writeln(dem);{Xuất dem} readln; end. Bài 7: { Viết chơng trình nhập vào một chuỗi kí tự a. Tính các tập sau - Tập A chỉ chứa các chữ cái hoa - Tập B chỉ chứa các chữ cái thờng - Tập C chỉ chứa các chữ số - Tập D chứa mọi kí tự con lại b. In ra màn hình các tập đó} uses crt; var s:string;{Xâu S} a,b,c,d:set of char;{Tập a,b,c,d kiểu kí tự} i:byte;{i kiểu byte} ch:char;{ch kiểu kí tự} begin clrscr;{Xoá màn hình} write('S = ');readln(S);{Đọc S} a:=[];b:=[];c:=[];d:=[];{Gán a,b,c,d bằng rỗng} for i:=1 to length(s)do{Cho i chạy từ 1 đến chiều dài xâu S} if s[i]in['A' 'Z']then a:=a+[s[i]]{Nếu s[i]thuộc 'A' 'Z' thì cộng s[i] vào tập A} else if s[i]in['a' 'z']then b:=b+[s[i]]{Ngợc lại nếu s[i]thuộc 'a' 'a' thì cộng s[i] vào tập B} else if s[i]in['0' '9']then c:=c+[s[i]]{Ngợc lại nếu s[i]thuộc '0' '9' thì cộng s[i] vào tập C} else d:=d+[s[i]];{Ngợc lại nếu thì cộng s[i] vào tập D} writeln('Tap A'); for ch:='A' to 'Z' do{Cho ch chạy từ 'A' đến 'Z'} if ch in a then write(ch,' ');{Nếu ch thuộc tập A thì xuất ch} writeln; writeln('Tap B'); for ch:='a' to 'z'do{Cho ch chạy từ 'a' đến 'a'} if ch in b then write(chr(i),' ');{Nếu ch thuộc tập B thì xuất ch} writeln; writeln('Tap C'); for ch:='0' to '9'do{Cho ch chạy từ '0' đến '9'} if ch in c then write(chr(i),' ');{Nếu ch thuộc tập C thì xuất ch} writeln; writeln('Tap D'); for i:=0 to 255 do{Cho i chạy từ 0 đến 255} if chr(i)in d then write(chr(i),' ');{Nếu kí tự có mã i thuộc tập D thì xuất kí tự đó} readln; end. Bài 8: { Viết thủ tục tracnghiem(s,sa,sb,sc,sd:string;kq:char); Thủ tục sẽ in ra câu hỏi s và các câu lựa chọn sa,sb,sc,sd. Sau đó chơng trình sẽ đợi đến khi ngời dùng ấn các phím A,B,C,D. So sánh kết quả đó với kq. Nếu đúng thì in ra "Ban tra loi dung" ngợc lại in ra " Ban tra loi sai"} uses crt; procedure tracnghiem(s,sa,sb,sc,sd:string;kq:char); var ch:char;{Khai báo ch kiểu kí tự} begin clrscr;{Xoá màn hình} writeln(s);{Xuất S} writeln(sa);{Xuất sa} writeln(sb);{Xuất sb} writeln(sc);{Xuất sc} writeln(sd);{Xuất sd} repeat ch:=upcase(readkey) until ch in['A' 'D'];{Nhận ch cho đến khi ch là các phím A,B,C,D} if ch=upcase(kq)then writeln('Ban tra loi dung'){Nếu ch bằng kí tự kq thì xuất Đúng} else writeln('Ban tra loi sai');{Ngợc lại thì xuất Sai} readln; end; begin tracnghiem('Bo nho co may loai','a. 1','b. 2','c. 3','d. 4','b'); end. 8 8888888888888888888888888888888888888888888888888888888888888888888888 8888888888888888888888888888888888888888888888888888888888888888888888 8888888888888888888888888888888888888888888888888888888888888888888888 8888888888888888888888888888888888888888888888888888888888888888888888 88888888888888888888 . Kiểu tập hợp I. Kiểu tập hợp Một tập hợp bao gồm một số đối tợng nào đó có cùng bản chất. Trong Pascal điều đó có ngiã là mô tả. nhau 2. Phép hợp Hợp của 2 tập là một tập có các phần tử thuộc hai tập Đợc kí hiệu bằng dấu + VD : A := [3 5]; B := [4 6,10,123]; C := A+B; { Tập C sẽ là