Xây dựng lớp biểu diễn một bảng băm sử dụng một trong những hàm băm đãhọc 2.. Sử dụng lớp bảng băm để xây dựng lớp quản lý một thư viện giúp người quảnlý thư viện có thể tra cứu nhanh mộ
Trang 1KHOA CÔNG NGHỆ THÔNG TIN -o0o -
Bài tập lớn môn học
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
Giảng viên hướng dẫn: TS Hoàng Văn Thông Sinh viên thực hiện: Vũ Đức Thành
Lớp: CNTT 3
Hà Nội tháng 11 năm 2023
Trang 2▪ Nạp thông tin sánh của thư viện từ file vào bảng băm 2
▪ Tìm kiếm bằng phương pháp tìm kiếm trên bảng băm 2
▪ Thêm sách mới vào thư viện 2
▪ Xóa sách khi biết tên 2
▪ Lưu thông tin thư viện vào file 2
1.2 Phân tích bài toán 2
1.3.Cài đặt các lớp và hàm main bằng C++ 4
1.4.Phân tích thời gian chạy của từng phương thức trong các lớp 9
BÀI 2 (Bài 28 trong danh sách bài tập) 12
2.1 Đề bài 12
1. Cài đặt lớp từ điển dựa trên bảng băm với hàm băm là tổng mã ASCII của các ký tự của khóa chia dư cho 997 12
2. Từ điển bao gồm các chức năng: 12
a. Chèn cặp từ tiếng Anh và từ tiếng Việt vào từ điển với khóa là từ tiếng Anh 12b. Lấy nghĩa của từ tiếng Việt với đầu vào là một từ tiếng Anh 12
c. Xóa cặp từ khỏi từ điển 12
d. Cập nhật một từ đã có trong từ điển 12
e. Đọc dữ liệu từ một tệp tin (file) để chèn vào từ điển 12
f Xuất dữ liệu của từ điển ra một tệp tin (file) 12
2.2 Phân tích bài toán 12
DANH SÁCH TÀI LIỆU THAM KHẢO 20
1
Trang 3BÀI 1 (Bài 14 trong danh sách bài tập)1.Đề bài
1 Xây dựng lớp biểu diễn một bảng băm sử dụng một trong những hàm băm đãhọc
2 Sử dụng lớp bảng băm để xây dựng lớp quản lý một thư viện giúp người quảnlý thư viện có thể tra cứu nhanh một loại sách nào đó nằm ở đâu trong thư viện.Với các phương thức:
▪ Nạp thông tin sánh của thư viện từ file vào bảng băm ▪ Tìm kiếm bằng phương pháp tìm kiếm trên bảng băm ▪ Thêm sách mới vào thư viện
▪ Xóa sách khi biết tên ▪ Lưu thông tin thư viện vào file
1.2 Phân tích bài toán
Yêu cầu của bài toán
Xây dựng lớp biểu diễn một bảng băm Xây dựng một lớp quản lý một thư viện giúp người quản lý thư viện có
thể tra cứu nhanh vị trí của các loại sách với 1 số phương thức: Thêm sáchmới, tìm kiếm, xóa sách
Xác định các lớp, các thuộc tính, phương thức của lớp và chứcnăng
* Hàm băm:Hàm băm được sử dụng để chuyển đổi từ khóa thành chỉ số (giá trị băm)
trong mảng lưu trữ các giá trị tìm kiếm
Hàm băm sử dụng trong bài toán được đặt ra: lấy tổng mã ASCII củatừng kí tự trong chuỗi tiếng Anh, sau đó chia lấy dư cho 997
int Hash(string str){ //tao 1 hashint n=str.size();
int res=0;for(int i=0; i<n; i++){
res+=(str[i]%997); // cong ma ascii}
return res%997; // tong cac so dai dien cho ki tu mk vua nhap vao}
2
Trang 4 Lớp Hashtable : Định nghĩa một bảng băm
Bảng băm là một cấu trúc dữ liệu dùng để chứa cặp key/value Sử
dụng hàm băm như 1 ánh xạ tuyến tính để chèn hoặc tìm kiếm dữliệu dễ dàng hơn Trong trường hợp lý tưởng, việc thao tác với cácphần tử trong bảng băm sẽ có độ phức tạp O(1
void xuat( string tenfile): Hàm ghi dữ liệu từ thư viện ra 1 file mới
Lớp book: Quản lí thông tin quyển sách trong thư viện
Các thuộc tính:
string ma=""; string ten=""; string vitri=""; int sl=0; Các phương thức
book(int temp=0): Hàm tạo có đối của lớp book khơi tạo vị trí ban đầucho cuốn sách
void nhap(): Hàm nhập thông tin cho mỗi cuốn sách ( tên, mã, số lượng,vị trí)
3
Trang 5 friend ostream & operator <<(ostream &os, book &bk): Hàm nạp chồngtoán tử “<<”
bool operator ==(long long a): Hàm nạp chồng toán tử “==” trả vềgiá trị NULL
1.3.Cài đặt các lớp và hàm main bằng C++
#include<iostream>#include"vector.cpp"using namespace std;int Hash(string str){ //tao 1 hash
int n=str.size(); int res=0;for(int i=0; i<n; i++){
res+=(str[i]%997); // cong ma ascii}
return res%997; // tong cac so dai dien cho ki tu mk vua nhap vao}
template <class k, class v>class Hashtable{
int n;vector<pair<k,v>> *table;public:
Hashtable(int n=1000){ //n ko dai dien cho kich thuoc //pair laf 1cap
this->n=n;table = new vector<pair<k,v>>[n];}
void put( k key, v value){ int temp= Hash(key)%n;for(int i=0; i<table[temp].size();i++){
if(table[temp][i].first==key){table[temp][i].second=value;return;
4
Trang 6}}table[temp].push_back({key,value}); //1 cap thi cho vao ngoac nhon}
v get(k key){ //// lay ra valueint temp=Hash(key)%n; // chuyen ve ngan nhofor(pair<k,v> it:table[temp]){ //voi moi cap doi it nam o trong bang o vitri temp
if(it.first==key) return it.second;}
return 0;}
bool contains(k key){// co trong ht hay koint temp=Hash(key)%n; // chuyen ve ngan nhofor(pair<k,v> it:table[temp]){ //voi moi cap doi it nam o trong bang o vitri temp
if(it.first==key)return true;}
return false;}
void xuat( string tenfile){fstream f (tenfile,ios::out);for(int i=0; i<n; i++){
for(int j=0;j<table[i].size(); j++){f<<table[i][j].first<<endl<< table[i][j].second<<endl;}
}f.close(); }
// File chạy chương trình#include<iostream>#include"hashtable.cpp"
5
Trang 7using namespace std;
class book{public:string ma="";string ten="";string vitri="";int sl=0;book(int temp=0){}
void nhap(){
cin.ignore();cout<<"nhap ma sach: ";getline(cin,ma);cout<<"nhap ten: ";getline(cin,ten);cout<<"nhap vitri: ";getline(cin,vitri);cout<<"nhap so luong: ";cin>>sl;
}friend ostream & operator <<(ostream &os, book &bk){
os<<bk.ma<<endl<<bk.ten<<endl<<bk.vitri<<endl<<bk.sl<<endl;return os;
}bool operator==(long long a){
return ma=="" && a==0;}
};int main(){
6
Trang 8while(true){int luachon; cout<<"nhap lua chon:"<<endl;cout<<"1 nap thong tin sach tu 1 file "<<endl;cout<<"2.tim kiem "<<endl;
cout<<"3 Them sach "<<endl;cout<<"4 xoa sach"<<endl;cout<<"5 luu thong tin thu vien vao file"<<endl;cout<<"6 Thoat"<<endl;
cin>>luachon;if (luachon==1){
fstream fs; fs.open("input_14.txt");
if (!fs.is_open()) { cout << "Mo file that bai!"; return 1;
}string key; book bk; while (getline(fs, key)) { getline(fs, bk.ma);
getline(fs,bk.ten);getline(fs,bk.vitri);fs>>bk.sl;fs.ignore();fs.ignore();ht.put(bk.ten,bk);
7
Trang 9}
fs.close(); }
else if(luachon==2){string ten; cin.ignore();cout<<"moi bn nhap ten sach can tim: "; getline(cin,ten);
cout<<"\nten minh vua nhap vao: "<<ten<<endl;book a=ht.get(ten);
if(a==0) cout<<"\nko co cuon sach can tim";else {
cout<<"sach can tim: ";cout<<a;
}
}else if(luachon==3){
book a;a.nhap();ht.put(a.ten,a);}
else if(luachon==4){string ten;cout<<"moi bn nhap ten sach: ";cin.ignore();
getline(cin,ten);ht.put(ten,book());
}else if(luachon==5){
ht.xuat("out_14.txt");
8
Trang 10}}
1.4.Phân tích thời gian chạy của từng phương thức trong các lớp1 Hàm Hash (string str){ //tao 1 hash
int n=str.size(); int res=0;
2 lệnh trên dung để dán nên thời gian chạy O(1)🡪
for(int i=0; i<n; i++){ res+=(str[i]%997); cộng giá trị của mã ascii qua lần lượt từngphần tử của chuỗi
Thời gian chạy O(n) ( với n là độ dài của chuỗi nhập vào)
}return res%997; // tong cac so dai dien cho ki tu mk vua nhap vao
Phép trả về vị trí đại diện cho kí tu vua nhập có thời gian chạy O(1)
}Time complexity: O(n).( hay O(str.size())
🡪
2 Lớp Hashtable:
* Hashtable(int n=1000){ this->n=n;table = new vector<pair<k,v>>[n];}
Time complexity: O(1)
* put( k key, v value){ int temp= Hash(key)%n; // O(1)for(int i=0; i<table[temp].size();i++){ // tim kiem ptu do có xh trong bangchua
if(table[temp][i].first==key){table[temp][i].second=value;return;
9
Trang 11}}table[temp].push_back({key,value}); //O(1)
}Mỗi bảng băm có n hang và hashtable.size()), số phần tử đc chia vào các
🡪
hang
Nếu th tốt nhất ko có phần tử nào trùng hang O(1)🡪TH trung bình thì thời gian chạy O( hashtable.size()/n)TH xấu nhất tát cả các phần tử trùng hang O(hashtable.size() )🡪
Thời gian chạy của phép gán và phép trả về O(1)
🡪
}return 0;
Mỗi bảng băm có n hang và hashtable.size()), số phần tử đc chia vào các
🡪
hang
Nếu th tốt nhất ko có phần tử nào trùng hang O(1)🡪TH trung bình thì thời gian chạy O( hashtable.size()/n)TH xấu nhất tát cả các phần tử trùng hang O(hashtable.size() )🡪
*bool contains(k key){// co trong ht hay ko
int temp=Hash(key)%n; // chuyen ve ngan nhofor(pair<k,v> it:table[temp]){ //voi moi cap doi it nam otrong bang o vi tri temp
if(it.first==key)return true;}
return false;}
Mỗi bảng băm có n hang và hashtable.size() phần tử), số phần tử đc chia
🡪
vào các hang
Nếu th tốt nhất ko có phần tử nào trùng hang O(1)🡪TH trung bình thì thời gian chạy O( hashtable.size()/n)TH xấu nhất tát cả các phần tử trùng hang O(hashtable.size() )🡪
*void xuat( string tenfile){
fstream f (tenfile,ios::out);for(int i=0; i<n; i++){ Duyệt qua lần lượt từng phần tử trong bảng băm
10
Trang 12Thời gian chạy: O(n)🡪
for(int j=0;j<table[i].size(); j++){ Duyệt lần lượt các phần tử cótrên 1 hàng của bảng
Thời gian chạy:O(table[i].size());🡪
f<<table[i][j].first<<endl<< table[i][j].second<<endl;}
}
Time complexity: O(n*table[i].size() ) ( với n là số phần tử của mảng)
🡪
3 Lớp book:void nhap(){
cin.ignore();cout<<"nhap ma sach: ";getline(cin,ma); // Lấy hết kí tự đc nhập vào cho tới hết dòng Time complexity: O(ma.size())
🡪
cout<<"nhap ten: ";getline(cin,ten);Time complexity: O(ten.size())🡪
cout<<"nhap vitri: ";getline(cin,vitri);Time complexity: O(vitri.size())🡪
cout<<"nhap so luong: ";cin>>sl;
Time complexity: O(1)🡪
}
🡪Time complexity: O(m+n+k) ( với m,n,k là độ dài của xâu ma, ten, vitri)
friend ostream & operator <<(ostream &os, book &bk){
os<<bk.ma<<endl<<bk.ten<<endl<<bk.vitri<<endl<<bk.sl<<endl;return os; // tra ve du lieu xuat ra;
}
🡪Time complexity: O(1)
bool operator==(long long a){
return ma=="" && a==0;// Hàm kiểm tra xem thuộc tính mã có bằng NULL hay ko
Time complexity: O(1)
🡪
11
Trang 13BÀI 2 (Bài 28 trong danh sách bài tập)
2.1 Đề bài
1.Cài đặt lớp từ điển dựa trên bảng băm với hàm băm là tổng mã ASCII củacác ký tự của khóa chia dư cho 997
2.Từ điển bao gồm các chức năng:
a.Chèn cặp từ tiếng Anh và từ tiếng Việt vào từ điển với khóa là từ tiếngAnh
b.Lấy nghĩa của từ tiếng Việt với đầu vào là một từ tiếng Anh
c.Xóa cặp từ khỏi từ điển
d.Cập nhật một từ đã có trong từ điển
e. Đọc dữ liệu từ một tệp tin (file) để chèn vào từ điển
f. Xuất dữ liệu của từ điển ra một tệp tin (file)
2.2 Phân tích bài toán1 Yêu cầu của bài toán
Cài đặt lớp từ điển dựa trên bảng băm với hàm băm là tổng mã ASCII củacác ký tự của khóa chia dư cho 997
Từ điển với các chức năng: Thêm từ mới vào từ điển, lấy nghĩa của từ đãcó trong từ điển, thay đổi dữ liệu cho từ đã có trong từ điển, xóa từ trongtừ điển Ngoài ra còn có chức năng lấy dữ liệu từ 1 file và ghi dữ liệu trảlại file
2 Xác định các lớp, các thuộc tính, phương thức của lớp và chứcnăng
* Hàm băm:Hàm băm được sử dụng để chuyển đổi từ khóa thành chỉ số (giá trị băm)
trong mảng lưu trữ các giá trị tìm kiếm
Hàm băm sử dụng trong bài toán được đặt ra: lấy tổng mã ASCII củatừng kí tự trong chuỗi tiếng Anh, sau đó chia lấy dư cho 997
int Hash(string str){ //tao 1 hashint n=str.size();
int res=0;
12
Trang 14for(int i=0; i<n; i++){res+=(str[i]%997); // cong ma ascii}
return res%997; // tong cac so dai dien cho ki tu mk vua nhap vao}
Lớp Hashtable : Định nghĩa một bảng băm
Bảng băm là một cấu trúc dữ liệu dùng để chứa cặp key/value Sử
dụng hàm băm như 1 ánh xạ tuyến tính để chèn hoặc tìm kiếm dữliệu dễ dàng hơn Trong trường hợp lý tưởng, việc thao tác với cácphần tử trong bảng băm sẽ có độ phức tạp O(1
int n=str.size(); int res=0;
13
Trang 15for(int i=0; i<n; i++){res+=(str[i]%997); // cong ma ascii}
return res%997; // tong cac so dai dien cho ki tu mk vua nhap vao}
template <class k, class v>class Hashtable{
int n;vector<pair<k,v>> *table;public:
Hashtable(int n=1000){ //n ko dai dien cho kich thuoc //pair laf 1cap
this->n=n;table = new vector<pair<k,v>>[n];}
void put( k key, v value){ int temp= Hash(key)%n;for(int i=0; i<table[temp].size();i++){
if(table[temp][i].first==key){table[temp][i].second=value;return;
}}table[temp].push_back({key,value}); //1 cap thi cho vao ngoac nhon}
v get(k key){ //// lay ra valueint temp=Hash(key)%n; // chuyen ve ngan nhofor(pair<k,v> it:table[temp]){ //voi moi cap doi it nam o trong bang o vitri temp
if(it.first==key) return it.second;}
14
Trang 16return 0;}
bool contains(k key){// co trong ht hay koint temp=Hash(key)%n; // chuyen ve ngan nhofor(pair<k,v> it:table[temp]){ //voi moi cap doi it nam o trong bang o vitri temp
if(it.first==key)return true;}
return false;}
void xuat( string tenfile){fstream f (tenfile,ios::out);for(int i=0; i<n; i++){
for(int j=0;j<table[i].size(); j++){f<<table[i][j].first<<endl<< table[i][j].second<<endl;}
}f.close(); }
// Hàm main để chạy chương trình // Sử dụng hàm băm bnagwf file “ Hashtable.cpp”#include<iostream>
#include"hashtable.cpp"using namespace std;
int main(){Hashtable<string,string> ht;while(true){
int luachon;cout<<"moi ban nhap lua chon:"<<endl;
15
Trang 17cout<<"1 chen 1 tu vao tu dien"<<endl;cout<<"2 lay nghia cua tu tieng anh"<<endl;cout<<"3 xoa mot tu trong tu dien"<<endl;cout<<"4 cap nhap mot tu da co trong tu dien"<<endl;cout<<"5 doc du lieu tu mot tep tin de chen vao tu dien"<<endl;cout<<"6 xuat du lieu tu dien ra mot tep tin"<<endl;
cout<<"0 thoat"<<endl;cin>> luachon;if(luachon==1){
string ta, tv; cin.ignore();cout<<"nhap tu tieng anh: "; getline(cin,ta); cout<<"\nnhap tu tieng viet: "; getline(cin,tv);ht.put(ta,tv);
}else if(luachon==2){string ta; cout<<"nhap ta: ";cin.ignore();getline(cin,ta);if(ht.contains(ta)==false)
cout<<"ko ton tai "<<endl;else
cout<<"tieng viet: "<<ht.get(ta)<<endl;
}else if(luachon==3){string ta; cout<<"nhap ta: ";cin.ignore();getline(cin,ta);ht.put(ta, "");
16
Trang 18}else if(luachon==4){string ta, tv; cin.ignore();cout<<"nhap tu tieng anh: "; getline(cin,ta); cout<<"\nnhap tu tieng viet: "; getline(cin,tv);ht.put(ta,tv);
}else if(luachon==5){
fstream fs; fs.open("input_28.txt");
if (!fs.is_open()) { cout << "Mo file that bai!"; return 1;
}
string str[100]; int i = 0;
while (getline(fs, str[i])) { i++;
} for (int j = 0; j < i; j ++) {
cout<<str[j]<<endl; }
for (int j = 0; j < i; j += 2) {
ht.put(str[j],str[j+1]); }
fs.close();
}else if(luachon==6){ht.xuat("out_28.txt");
17