Tải bản đầy đủ (.doc) (58 trang)

cac phuong phap tim kiem trong

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (889.74 KB, 58 trang )

TRƯỜNG ĐẠI HỌC VINH
KHOA: CNTT

ĐỀ TÀI THỰC TẬP CƠ SỞ
- MÃ ĐỀ: 002

PHẦN 1 - CÁC PHƯƠNG PHÁP TÌM KIẾM TRONG
Các phương pháp tim khiếm trong: Tìm kiếm tuần tự, tìm kiếm nhị phân,
cây nhị phân tìm kiếm.
Yêu cầu:
1. Trình bày thuật tốn
2. Ví dụ minh hoạ
3. Cài đặt thuật tốn trên một ngơn ngữ nào đó ( Pascal, C, C++)
PHẦN 2 - DÙNG WORD VỚI E-MAIL
Yêu cầu:
1. Những yêu cầu hệ thống để gửi e-mail từ Word
2. Gửi e-mail message từ Word
3. Gửi một tài liệu Word như một file đính kèm với e-mail
PHẦN 3 - MA TRẬN
1. Cài đặt thuật toán về ma trận:
- Cộng ma trận.
- Nhân ma trận.
-Tính định thức ma trận.
2. Xây dựng Menu để thực hiện các chức năng:
- Dữ liệu vào: Tệp số liệu.
- Dữ liệu ra: Tệp số liệu kết quả.
PHẦN 4 :
Tỡm hiểu và khai thỏc dịch vụ Windos Firewall của Windows.


phần 1 - các phơng pháp tìm kiếm trong


Các phơng pháp tim khiếm trong: Tìm kiếm tuần tự, tìm
kiếm nhị phân, cây nhị phân tìm kiếm.
Yêu cầu:
4. Trình bày thuật toán
5. Ví dụ minh hoạ
6. Cài đặt thuật toán trên một ngôn ngữ nào đó
( Pascal, C, C++)
*********************
Tỡm kim(Searching ) là một đòi hỏi rất thường xuyên trong đời sống hàng
ngày cũng như trong xử lí tin học.
Bài tốn tìm kiếm được phát biểu như sau:
Cho một bảng gồm n bản ghi R1,R2,…,Rn. Mỗi bản ghi Ri tương ứng
với một khóa Ki. Hãy tìm bản ghi có giá trị khóa tương ứng bằng X cho
trước.
X được gọi là khóa tìm kiếm hay đối trị tìm kiếm (argument). Cơng việc tìm
kiếm sẽ hồn thành khi có 1 trong hai tình huống sau đây xảy ra.
- Tìm được bản ghi có giá trị khóa bằng X, khi đó ta nói phép tìm
kiếm được thỏa mãn (successfull).
- Khơng tìm được bản ghi có khóa bằng X, khi đó ta nói phép tìm
kiếm khơng được thỏa mãn (unsuccessfull).Nếu phép tìm khơng thỏa mãn
cịn có yêu cầu bổ sung thêm 1 bản ghi mới có giá trị khóa bằng X thì giải
thuật tương ứng được gọi là "giải thuật tìm kiếm có bổ sung".
Tương tự như các phương pháp sắp xếp, khóa của mỗi bản ghi chính là đặc
điểm nhận biết của bản ghi đó trong tìm kiếm, ta sẽ coi nó như đại diện cho
bản ghi ấy và trong các giải thuật. Để thuận tiện ta cũng coi các khóa k i
(1<=i<=n) là các số khác nhau.


I. TÌM KIẾM TUẦN TỰ (sequential searching)
I.1 - Tìm kiếm tuần tự là kỹ thuật rất đơn giản và cổ điển

Nội dung có thể tóm tắt như sau:
" Bắt đầu từ bản ghi thứ nhất, lần lượt so sánh khóa tìm kiếm với khóa
tương ứng của các bản ghi trong bảng, cho tới khi tìm được bản ghi mong
muốn hoặc đã hết bảng mà chưa thấy ".
Giải thuật tìm kiếm sau đây sẽ trả về vị trí tìm thấy khóa X hoặc trả về giá trị
0 nếu khơng tìm thấy:
Int Sequence_search( k, n,X)
1
i=0;
while((i<=n)&&(k[i]!=X)) i=i+1;
2. {Trả về vị trí }
If(i==n+1) return 0;
Else return I;
Các modul chính của chương trình
// khai bao cau truc phan tu
typedef struct phantu
{ int khoa;
char noidung[30];
}phantu;
//+++++ ham tim kiem tuan tu ,tra ve vi tri neu tim tra ve vi tri tim thay
int search_tuantu(phantu *p,int kh,int n)
{ int i=0;
while((i

if (i==n)return 0;
else return i+1;
}
//****************************************************
void tuantu()

{
phantu p[4];
int i;
for( i=0;i<4;i++)
{printf("\n nhap khoa :");scanf("%d",&p[i].khoa);
printf("\n nhap noi dung");scanf("%s",&p[i].noidung);
}
printf("\n\n\n Danh sach sau khi da nhap : ");
for(i=0;i<4;i++)
{ printf("\n khoa %d",p[i].khoa);
printf("\n noi dung : %s",p[i].noidung); }
int k;
int n=4,l;
cout<<"\n nhap khoa can tim ";cin>>k;
l=search_tuantu(p,k,n);
if(l==0)printf("\n\n Khong tim thay !!!");
else printf("\n\n Tim thay o vi tri thu %d",l);
getch();
}
I.2 Nhận xét:
Ở đây để đánh giá hiệu lực của phép tìm kiếm ta cũng dựa vào số
lượng các phép so sánh. Ta thấy với giải thuật trên thuận lợi chỉ cần phép so


sánh: Cmin=1; cịn xáu nhất thì Cmax=n+1.Nếu giả sử hiện tượng khóa tìm
kiếm trùng với một khóa nào đó của bảng là đồng khả năng thì
Ctb=(n+1)/2.Tóm lại cả hai trường hợp xấu nhất cũng như trung bình, cấp độ
lớn của thời gian thực hiện giải thuật trên là O(n).
Nhưng nếu xác suất xuất hiện K i=X mà Pi≠ 1/n thì sao? Lúc đó ta sẽ có
Ctb=1*P1+2*P2+….+n*Pn.

n

Với

∑p
i =1

i

=1

Rõ ràng là nếu P1≥P2≥….≥Pn thì thời gian trung bình sẽ nhỏ hơn. Nhưng
muốn như vây thì phải sắp xếp trước !
II. TÌM KIẾM NHỊ PHÂN (Binary searching)
II.1 Mơ tả thuật tốn
Tìm kiếm nhị phân là một phương pháp tìm kiếm khá thơng dụng.
Nó dựa trên sự ứng dụng của sơ đồ "chia để trị". Phép tìm kiếm nhị phân
phải ln ln chọn khóa ở giữa dãy khóa đang xét để so sánh với khóa tìm
kiếm. Giả sử dãy khóa đang xét là : K1,Kl+1,…,Kh thì khóa ở giữa dãy khóa
đang xét là khóa Km, m=(l+h) div 2. Việc tìm kiếm kết thúc nếu X=Km.
Nếu X….,Km-1; cịn nếu X>Km : phép tìm kiếm được thực hiện tương tự trên dãy
khóa Km+1,Km+2,….,Kh.
Như vậy để có thể thực hiện tìm kiêm nhị phân được địi hỏi dãy khóa phải
được sắp xếp tăng dần.
Ví dụ:


Cho dãy khóa K đã được sắp xếp tăng dần giải thuật tìm kiếm sau sẽ
trả về vị trí tìm thấy khóa X hoặc trả về giá trị O nếu khơng tìm thấy.

Ta mơ phỏng thuật tốn bằng ngơn ngữ giả Pascal:
Function Binary_Search(K,n,X)
1.{Khởi tạo}
L:=1;h:=n;
2.{Tìm kiếm}
While(l ≤ h) do
Begin
m:=(l+ h) div 2;
if(Xelse
if(X> K[m]) then l:=m+1
else return (m);
end;
3. return (O).


Ta có thể cài đặt thuật tốn bằng dười dạng đệ quy.
1. Phạm vi tìm kiếm ban đầu là tồn bộ danh sách k=0 đến h=n-1(n là số
lượng phần tử).
2. Lấy phần tử chính giữa của phạm vi tìm kiếm K[m] rồi so sánh với X
• Nếu K[m]=X, trả về chỉ số j. dừng lại.
• Nếu K[m]>X,phạm vi tìm kiếm mới là các phẩn tử có chỉ số nhỏ
hơn m. Gọi đệ quy hàm tìm kiếm với phạm vi mới là (l,m-1).
• Nếu K[m]hơn m. Gọi đệ quy hàm tìm kiếm với phạm vi mới là (m+1,h).
• Điều kiện dừng X=K[m] hoặc l>h.
Cài đặt thuật toán:
Int Binary_search1(int K[],int l,int h,int X)
{
Int m=(l+h)/2;

If(l>h) return -1;
Else if(K[m]==X) return j;
Else Binary_search1(K,(K[m]<X?m+1:l),(K[m]>X?m-1:h),X);
}
Các modul chính của chương trình :
// khai b¸o cÊu tróc phÇn tư
typedef struct phantu
{ int khoa;


char noidung[30];
}phantu;
*/
// hàm sắp xếp
void sapxep(phantu *a,int n)
{ phantu tg;
for(int i=0;ifor(int j=i+1;jif(a[i].khoa>a[j].khoa)
{ tg=a[i];
a[i]=a[j];
a[j]=tg;
}
}
// hàm tìm kiếm nhị phân
int search_nhifan(phantu *p,int kh,int n)
{
int l=0,r=n+1,m;
sapxep(p,n);
while(l<=r)

{ m=(l+r)/2; // lay vi tri cua phan tu giua
if(p[m].khoa>kh)r=m-1;
// nếu phần tử lớn hơn khoá thì tiếp tục tìm
// khoảng trớc phần tử giữa m
else
if(p[m].khoa

// nếu pt giữa nhỏ hơn khoá sẽ tiếp tục tìm ở khoảng sau
pt giữa
else return m ; // nếu bằng trả về vị trí tìm thấy
}
return -1; // không tìm thấy trả về 0
}
void tknhifan()
{
phantu p[4];
for(int i=0;i<4;i++)
{printf("\n nhap khoa : ");scanf("%d",&p[i].khoa);
printf("\n nhap noi dung : ");scanf("%s",&p[i].noidung);
}
printf("\n\n\n Danh sach sau khi da nhap : ");
for(i=0;i<4;i++)
{ printf("\n khoa %d",p[i].khoa);
printf("\n noi dung : %s",p[i].noidung);
}
//********************
printf("\n\n Danh sach sau khi sap xep ");
sapxep(p,4);
for(i=0;i<4;i++)

{ printf("\n Khoa : %d",p[i].khoa);
printf("\n noi dung : %s",p[i].noidung);
}
int k;


int n=4,l;
cout<<"\n\n\n nhap khoa can tim ";cin>>k;
l=search_nhifan(p,k,n);
if(l==-1)printf("\n\n Khong tim thay !!!");
else printf("\n\n Tim thay o vi tri thu %d",l+1);
getch();
}
II.2 Nhận xét
- Với giải thuật được viết dưới dạng đệ quy người ta đã chứng minh
được rằng chi phí thời gian trong trường hợp xấu nhất và trung bình
đều là O(log2n).
- Khi sử dụng giải thuật tìm kiếm nhị phân địi hỏi dãy khóa phải được
sắp xếp rồi nghĩa là chi phí thời gian cho sắp xếp cũng phải được kể
đến.Nếu dãy khóa ln biến động thì chi phí cho sắp xếp nổi lên rất rõ
và đây chính là nhược điểm của phương pháp tìm kiếm nhị phân.
III. CÂY NHỊ PHÂN TÌM KIẾM (BST- Binary Search Tree)
III.1- Các khái niệm về cây và cây nhị phân.
Cây là một cấu trúc dữ liệu rất thông dụng và quan trọng trong nhiều
phạm vi khác nhau của kỹ thuật máy tính.
Ví dụ : Tổ chức các quan hệ họ hàng trong một gia phả, mục lục của một
cuốn sách, xây dụng cấu trúc cú pháp trong các trình biên dịch.
+ Các khái niệm
Cây là tập hợp các phần tử gọi là nút (một nút có thể có kiểu bất
kỳ)


và tâp các cạnh có hướng kết nối các cặp nút trong cây.


Ví dụ: xét mục lục của một quyển sách. Mục lục này có thể xem là một cây

Nút gốc (Root): là nút ở "trên cùng" trong một cây. Trên nút gốc khơng có
nút nào nữa.
Nút con (Child): nút kế tiếp (phía dưới) của một nut trong cây. Một nút có
thể có nhiều nút con, các nút con này được nhìn theo thứ tự từ trái sang phải.
Nút con tận cùng bên trái là nút đầu tiên và nút con tận cùng bên phải là nút
con cuối cùng.
Nút cha (parent): nút liền kề (phía trên )của một nút trong cây.Một nút chỉ
có duy nhất một nút cha.
Các nút anh em (siblings): các nút con của cùng một nút.
Các cạnh/nhánh (edge/branch): đường nối từ nút cha đến các nút con của
nó.
Nút tổ tiên (ancestors): Các nút tổ tiên của một nút bao gồm nút cha của
nút,nút cha của nút cha,vvv..đến trên cùng là nút gốc.
Nút hậu duệ (descendant): Các nút hậu duệ của một nút bao gồm các nút
con của nút,các nút con của nút con,v.v. đến các nút là của các nhánh thuộc
nút.


Đường đi (Path): là chuỗi các cạnh nối từ một nút đến một trong số các nút
hậu dệu của nó.
Chiều dài đường đi (path length): số cạnh trong đường đi.
Nút lá (leaf): nút khơng có nút con
Nút trung gian (Interior node): nút có ít nhất một nút con.
Độ sâu hay mức của một nút (Depth/level): được tính bằng chiều dài

đường đi từ nút gốc đến nút đang xét.
Chiều cao của cây(height): chiều dài đường đi dài nhất trong cây.
Cây con (subtree): cây bao gồm nút và tất cả nút hậu duệ của nó. Nút gốc
và tồn bộ cây khơng được xem là cây con.
Cây nhị phân :
Trong cây nhị phân, mỗi nút có tối đa hai nút con: nút con nhánh trái và nút
con nhánh phải.
Khi một nút chỉ có một nút con, cần phải phân biệt là nut con bên nhánh trái,
hay nút con bên nhánh phải , chứ không chỉ đơn thuần gọi là nút con.


- Cây nhị phân tìm kiếm
* Định nghĩa cây nhị phân tìm kiếm
Cây nhị phân tìm kiếm ứng với n khóa K1,K2,..,Kn là một cây nhị phân
mà mỗi nút được gắn một giá trị khóa sao cho mọi nút trên cây đều thỏa
mãn các tính chất sau:
- Mọi khóa thuộc cây con trái của một nút đều có giá trị nhỏ hơn khóa ở
nút đó.
- Mọi khóa thuộc cây con phải của một nút đều có giá trị lớn hơn khóa
ở nút đó.
VD: biểu diễn dãy khóa sau thành cây nhị phân tìm kiếm:
42 23 74 65 58 94 36 99 87
4
2

2
3
1
1


7
4
3
6

6
5
5
8

9
4
8
7

9
9

* Giải thuật tìm kiếm
Để tìm xem khóa tìm kiêm X có ở trên cây hay khơng ta thực hiện như sau:
- So sánh X với khóa ở gốc khí đó một trong 4 tình huống sau đây sẽ
xuất hiện.
- Khơng có gốc(cây rỗng): X khơng có trên cây, phép tìm kiếm khơng
được thỏa mãn.
- X trùng với khóa ở gốc phép tìm kiêm được thỏa mãn.


- X nhỏ hơn khóa ở gốc: phép tìm kiếm được thực hiện tương tự trên
cây con trái.
- X lớn hơn khóa ở gốc: phép tìm kiếm được thực hiện tương tự cây con

phải.
Giả sử mỗi nút của cây nhị phân tìm kiếm có dạng
KEY
LPT
INFO
R
Trong đó:

RPTR

- Trường KEY chứa giá trị khóa
- Trường INFO chứa các thơng tin khác
- Trường LPTR và RPTR là con trỏ trỏ đến cây con trái và cây con phải
Cho cây nhị phân tìm kiếm có gốc trỏ bởi T. Giải thuật tìm kiếm sau sẽ trả
về địa chỉ nút có giá trị khóa =X, nếu khơng tìm thấy thì thực hiện bổ sung
vào cây.
FUNCTION BST ( T,X)
1.{Khi to}
P:=T;Q:=NULL;
// P trỏ vào cây, dùng P để dịch chuyển và kiểm tra
2.{Tỡm kim}
While ( P<>NULL) do
Case
X=key(P): return (P);
X< key(P) : // tìm kiếm bên trái
Begin
Q:=P;
P:=LPTR(P);



End.
X>key(P) : // tìm kiếm bên phải
Begin
Q:=P;
P:=RPTR(P);
End;
Endcase;
3. {To nỳt mi để bổ sung } // nếu không thấy sẽ bổ sung
NEW(P);
Key(P):=X;
LPTR(P):=RPTR(P):=NULL;
4. {Xét các trường hợp bổ sung }
Case
T=NULL: T:=P; // cây rỗng bổ sung P vào cây
X< key(Q) : LPTR(Q):=P;
X>key(Q) : RPTR(Q):=P;
Endcase ;
5. return (P).
Các modul chính của chương trình:
// khai b¸o kiĨu nodetype
struct nodetype
{
int key;
int info;
struct nodetype* left;


struct nodetype* right;
};
typedef struct nodetype *NHIFAN;

NHIFAN tree;
// hàm khởi tạo, khởi tạo giá nut gốc =NULL;
//************************************
void khoitao(NHIFAN *root)
{
*root=NULL;
}
// hàm cấp phát bộ nhớ tạo nút mới
//************************************************************
**
NHIFAN New_Node(void)
{
NHIFAN p;
p = (NHIFAN)malloc(sizeof(struct nodetype));
return (p);
}
//******HAM CHEN MOT NUT VAO CAY NHI FAN TIM ********
void Insert(NHIFAN root, int x, int a)
{NHIFAN p;
if(x == root->key) // kiem tra trung khoa
{
printf("\n\n\nError: trung khoa !!!\n khong them nut nay duoc");
return;
}


// trờng hợp cây con trái của nút gốc rỗng và bổ sung
khóa x vào bên trái
if(x < root->key && root->left == NULL)
{

p = New_Node();
p->key =x;
p->info = a;
p->left = NULL;
p->right = NULL;
root->left=p;
return;
}
//trờng hợp cây con trái của nút gốc rỗng và bổ sung
khóa x vào bên phải
if(x > root->key && root->right == NULL)
{
p = New_Node();
p->key =x;
p->info = a;
p->left = NULL;
p->right = NULL;
root->right=p ;
return;
}
// sử dụng hàm đệ quy để bổ sung
if(x < root->key)
Insert(root->left, x,a);


else
Insert(root->right, x,a);
}
// ***********hàm tạo cây nhị phân**************
void Create_Tree(NHIFAN &root)

{
khoitao(&root);
int khoa, noidung;
NHIFAN p;
do {
printf("\nNhap khoa :");scanf("d",&khoa);
if (khoa !=0)
{ printf("\nNhap noi dung :");scanf("%d",noidung);
if (root==NULL)
{ p = New_Node();
p->key = khoa;
p->info = noidung;
p->left = NULL;
p->right = NULL;
root =p;
}
else
Insert(root,khoa,noidung);
}
} while (khoa!=0); // dung lai khi nhap khoa =0
}


// hàm kiểm tra rỗng
int Is_NULL(NHIFAN root)
{return (root==NULL?1:0);}
// hàm tìm kiÕm
void Search(NHIFAN root, int x)
{
NHIFAN p,q=NULL;

p = root;
while(p != NULL) // trong khi p khác rỗng
{
if(x < p->key)
{q=p; // dung q để lưu vết và bổ sung nếu khơng tìm thấy khóa x;
p = p->left;} // tìm bên trái
if(x > p->key)
{ q=p;
p = p->right;}// tìm bên phải
if(x==p->key)
{ printf("\n\n da tim thay ");
// printf("\n noi dung %d",p->info);
return ;
}
}
// nếu không tìm thÊy th× bỉ sung
p=New_Node();
p->key=x;
p->right=p->left=NULL;
if(root==NULL){root=p;}


if(x<q->key)q->left=p;
if(x>q->key)q->right=p;
printf("\n\n khong thay , da bo sung ");
return ;}
// gi¶i phãng nót
void Free_Node(NHIFAN p)
{
free(p);

}
void main()
{ clrscr();
NHIFAN tree,p;
khoitao(&tree);
Create_Tree(tree);
int n,nd;
printf("\n\n nhap khoa can tim : ");scanf("%d",&n);
Search(tree,n);
getch();
}
III.2 Nhân xét :
Đối với phương pháp tìm kiếm trên cây nhị phân tìm kiếm người ta đã
chứng minh được rằng chi phí thời gian trong trường hợp xấu nhất và trung
bình đều là O(log2n) .
Người ta đã tính được rằng: cây nhị phân n phân tử, với n=1000, nó
cần khoảng 10 phép so sánh cho việc tìm kiếm, với n=1000000 thi nó cần


khoảng 20 phép so sánh, tuy nhiên với cây nhị phân khơng cân bằng hay kéo
dài thì thao tác tìm kiếm sẽ dài hơn.


PHẦN 2 - DÙNG WORD VỚI E-MAIL

Yêu cầu:
1. Những yêu cầu hệ thống để gửi e-mail từ Word
2. Gửi e-mail message từ Word
3. Gửi một tài liệu Word như một file đính kèm với e-mail
**********************

I - Những yêu cầu hệ thống để gửi E-mail từ word :
- Để tạo thông báo và gửi các thông báo E-mail từ word bạn phải có
Microsoft Outlook đính kèm với Office
- Outlook express được đính kèm với Internet Explorer
- Và một Microsoft Exchange client .
- Và một trong những các chương trình này được xác lập dưới dạng
chương trình E-mail mặc định
- Bạn nên cấu hình tài khoản thư của mình vơi Outlook để bạn có thể
kiểm tra thư và gửi thư trả lời. Tức là bạn phải có tài khoản POP3 và
SMTP để gửi và nhận E-mail .
Hiện nay có rất nhiều chỉ E-mail do nhiều nhà cung cấp có hỗ trợ
POP3 và mỗi địa chỉ đó có tài khoản POP3 riêng .
Tài khoản VNN, Gmail, Yahoo, Hotmail… có cấu hình POP3
I.1. Cỏch cấu hỡnh hũm thư Gmail
I.1.1 Cách cấu hình Gmail
+ Chọn cài đặt (Settings) ở góc trên bên phải trong hộp thoại cài đặt
thư (Mail Settings), chọn bảng chuyển tiếp và POP3 (Forwatdinh and POP),
chọn bật POP cho tất cả thư (Enable pop for all mail) hoặc chỉ bật POP cho
thư đến từ thời điểm này trở đi (Enable pop only for mail that arrives from
now on) trong mục khi thư được truy cập bằng POP chọn bản sao Gmail
sang thùng rác chọn lưu thay đổi (save changes).


I.1.2 Cỏch cấu hỡnh Outlook Express:
- Khởi động chương trỡnh Outlook Express
- Vào thực đơn Tools -> Accounts…
- Một cửa sổ tài khoản mở ra như sau:

- Chọn Add -> Chọn Mail…



Gừ vào tờn của bạn rồi chọn Next.

Gừ vào địa chỉ thư Gmail của bạn (có đi là gmail.com) rồi chọn
Next.


Gừ vào pop.gmail.com vào phần thứ nhất và smtp.gmail.com vào
phần thứ 2 (như hỡnh trờn). Chọn Next.

Gừ tờn tài khoản vào phần Account name (phần đầu của địa chỉ Email- trước biểu tượng @) và mật khẩu vào phần Password. Chọn Next.
- Chọn Finish để kết thúc.
- Bấm vào tài khoản vừa tạo chọn Properties.


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×