Tổng hợp bài giảng môn Kỹ thuật lập trình | Trường Đại học Bách Khoa Hà Nội

Số nguyên lớn: Làm thế nào để tính toán với số nguyên cực lớn, nghĩa là không thể lưu trữ bằng kiểu long long; Ý tưởng đơn giản: Lưu số nguyên dưới dạng string Tuy nhiên làm thế nào để tính toán số học giữa hai số nguyên? Có thể dùng thuật toán giống như phương pháp tính bậc tiểu học: tính từng chữ số, từng phần, có lưu phần nhớ

Cấu trúc dữ liệu Thư viện
THUẬT TOÁN ỨNG DỤNG
Đỗ Phan Thuận
thuandp.sinhvien@gmail.com
Bộ môn Khoa Học Máy Tính, Viện CNTT & TT,
Trường Đại Học Bách Khoa Nội.
Ngày 15 tháng 10 năm 2019
1 / 42
1
Các kiểu dữ liệu bản
2
Số nguyên lớn
3
Thư viện CTDL Thuật toán
Dequeue
Sắp xếp tìm kiếm
4
Biểu diễn tập hợp bằng Bitmask
5
Một số ứng dụng của CTDL
6
Cấu trúc dữ liệu mở
7
Biểu diễn đồ thị
2 / 42
1
Các kiểu dữ liệu bản
2
Số nguyên lớn
3
Thư viện CTDL Thuật toán
Dequeue
Sắp xếp tìm kiếm
4
Biểu diễn tập hợp bằng Bitmask
5
Một số ứng dụng của CTDL
6
Cấu trúc dữ liệu mở
7
Biểu diễn đồ thị
3 / 42
Các kiểu dữ liệu bản
Các kiểu dữ liệu phải biết:
I
bool: biến bun (boolean) (true/false)
I
char: biến nguyên 8-bit (thường được sử dụng để biểu diễn các tự
ASCII)
I
short: biến nguyên 16-bit
I
int: biến nguyên 32-bit
I
long long: biến nguyên 64-bit
I
float: biến thực 32-bit
I
double: biến thực 64-bit
I
long double: biến thực 128-bit
I
string: biến xâu tự
3 / 42
Các kiểu dữ liệu bản
Loại Số Byte Giá trị nhỏ nhất Giá trị lớn nhất
bool 1
char 1 -128 127
short 2 -32768 32767
int/long 4 -2148364748 2147483647
long long 8 -9223372036854775808 9223372036854775807
n 2
8n1
2
8n1
1
Loại
Số Byte Giá trị nhỏ nhất Giá trị lớn nhất
unsigned char 1 0 255
unsigned short 2 0 65535
unsigned int 4 0 4294967295
unsigned long long 8 0 18446744073709551615
n 0 2
8n
1
Loại Số Byte Giá trị nhỏ nhất Giá trị lớn nhất
float 4 3.4 × 10
38
3.4 × 10
38
7 chữ số
double 8 1.7 × 10
308
1.7 × 10
308
14 chữ số
4 / 42
1
Các kiểu dữ liệu bản
2
Số nguyên lớn
3
Thư viện CTDL Thuật toán
Dequeue
Sắp xếp tìm kiếm
4
Biểu diễn tập hợp bằng Bitmask
5
Một số ứng dụng của CTDL
6
Cấu trúc dữ liệu mở
7
Biểu diễn đồ thị
5 / 42
Số nguyên lớn
Làm thế nào để tính toán với số nguyên cực lớn, nghĩa không thể
lưu trữ bằng kiểu long long
Ý tưởng đơn giản: Lưu số nguyên dưới dạng string
Tuy nhiên làm thế nào để tính toán số học giữa hai số nguyên?
thể dùng thuật toán giống như phương pháp tính bậc tiểu học:
tính từng chữ số, từng phần, lưu phần nhớ
6 / 42
Bài toán dụ: Integer Inquiry
http://uva.onlinejudge.org/external/4/424.html
7 / 42
1
Các kiểu dữ liệu bản
2
Số nguyên lớn
3
Thư viện CTDL Thuật toán
Dequeue
Sắp xếp tìm kiếm
4
Biểu diễn tập hợp bằng Bitmask
5
Một số ứng dụng của CTDL
6
Cấu trúc dữ liệu mở
7
Biểu diễn đồ thị
8 / 42
Tầm quan trọng của cấu trúc dữ liệu
Nhiều khi dữ liệu cần được biểu diễn theo cách thuận lợi cho
I
Truy vấn hiệu quả
I
Chèn hiệu quả
I
Xóa hiệu quả
I
Cập nhật hiệu quả
Nhiều khi dữ liệu cần được biểu diễn theo cách tốt hơn nữa
I
Làm thế nào để biểu diễn số nguyên lớn?
I
Làm thế nào để biểu diễn đồ thị?
Các cấu trúc dữ liệu giúp chúng ta thực hiện được những điều này
9 / 42
Các cấu trúc dữ liệu thông dụng
Mảng tĩnh
- int arr[10]
Mảng động
- vector<int>
Danh sách liên kết
- list<int>
Ngăn xếp
- stack<int>
Hàng đợi
- queue<int>
Hàng đợi ưu tiên
- priority_queue<int>
Hàng đợi hai đầu
- deque<int>
Tập hợp
- set<int>
Ánh xạ
- map<int, int>, sử dụng y cân bằng đỏ đen
Thông thường nên sử dụng thư viện chuẩn
I
Gần như chắc chắn chy nhanh không lỗi
I
Giảm bớt việc viết code
Nhiều khi vẫn cần tự viết code thay dùng thư viện chuẩn
I
Khi muốn kiểm soát linh hoạt
I
Khi muốn tùy biến/hiệu chỉnh cấu trúc dữ liệu
10 / 42
Các cấu trúc dữ liệu thông dụng
Mảng tĩnh - int arr[10]
Mảng động - vector<int>
Danh sách liên kết - list<int>
Ngăn xếp - stack<int>
Hàng đợi - queue<int>
Hàng đợi ưu tiên - priority_queue<int>
Hàng đợi hai đầu - deque<int>
Tập hợp - set<int>
Ánh xạ - map<int, int>, sử dụng y cân bằng đỏ đen
Thông thường nên sử dụng thư viện chuẩn
I
Gần như chắc chắn chy nhanh không lỗi
I
Giảm bớt việc viết code
Nhiều khi vẫn cần tự viết code thay dùng thư viện chuẩn
I
Khi muốn kiểm soát linh hoạt
I
Khi muốn tùy biến/hiệu chỉnh cấu trúc dữ liệu
10 / 42
Các cấu trúc dữ liệu thông dụng
Mảng tĩnh - int arr[10]
Mảng động - vector<int>
Danh sách liên kết - list<int>
Ngăn xếp - stack<int>
Hàng đợi - queue<int>
Hàng đợi ưu tiên - priority_queue<int>
Hàng đợi hai đầu - deque<int>
Tập hợp - set<int>
Ánh xạ - map<int, int>, sử dụng y cân bằng đỏ đen
Thông thường nên sử dụng thư viện chuẩn
I
Gần như chắc chắn chạy nhanh không lỗi
I
Giảm bớt việc viết code
Nhiều khi vẫn cần tự viết code thay dùng thư viện chuẩn
I
Khi muốn kiểm soát linh hoạt
I
Khi muốn tùy biến/hiệu chỉnh cấu trúc dữ liệu
10 / 42
Deque - Hàng đợi hai đầu
Deque=Double-Ended Queue: CTDL tính chất của cả Stack
Queue, nghĩa cho phép thêm xóa cả hai đầu
# include <deque >
deque < string > myDeque ;
hỗ trợ tất cả các phương thức của kiểu vector list bao gồm cả chỉ
số con trỏ (iterator)
I
size() trả về kích thước của deque
I
front() trả về phần tử đầu tiên của deque
I
back() trả về phần tử cuối cùng của deque
I
push_front() thêm phần tử mới vào đầu của deque
I
push_end() thêm phần tử mới vào cuối của deque
I
pop_front() xóa phần tử đầu của deque
I
pop_end() xóa phần tử cuối của deque
11 / 42
Deque - Kiểm tra chuỗi Palindrome
12 / 42
Tùy biến kiểu priority_queue<int>
Trong nhiều trường hợp không thể dùng trực tiếp kiểu priority_queue
cần tùy biến lại để cài đặt thuật toán. dụ:
class Plane { // tuy bien priority queue min
public : int fuel
public : Pla ne ( int vQ ){(* this ). fuel = f uel ;}
friend ostream & operator < <( ostream & os , const Plane & p){
os <<p . fuel < < endl ; retur n os ;
}
bool operator >( c onst L abVer & p) const {
return fuel >p. fuel;
}
};
typedef priority_qu e ue < Plane , vector < Plane > , greater <Plane > > PQPlane ;
PQPlane PQ ;
int main (){
vector < Plane > vP;
vP. push_back ( P lane (4)); vP . push_back ( Plane (7));
vP. push_back ( P lane (3)); vP . push_back ( Plane (9));
PQPlane PQ ( vP. begin (), vP. end ());
while (! PQ . emp ty ()){ cout <<PQ. top (); PQ. pop ();}
return 0;
}
13 / 42
Sắp xếp Tìm kiếm
Các toán tử thông dụng nhất:
I
Sắp xếp một mảng - sort(arr.begin(), arr.end())
I
Tìm kiếm trên một mảng chưa sắp xếp - find(arr.begin(), arr.end(), x)
I
Tìm kiếm trên một mảng đã sắp xếp - lower_bound(arr.begin(),
arr.end(), x)
Thông thường nên sử dụng thư viện chuẩn
lúc cần phiên bản khác của tìm kiếm nhị phân nhưng bình thường
lower_bound đủ
hơn 90% sinh viên tự lập trình sai tìm kiếm nhị phân
14 / 42
1
Các kiểu dữ liệu bản
2
Số nguyên lớn
3
Thư viện CTDL Thuật toán
Dequeue
Sắp xếp tìm kiếm
4
Biểu diễn tập hợp bằng Bitmask
5
Một số ứng dụng của CTDL
6
Cấu trúc dữ liệu mở
7
Biểu diễn đồ thị
15 / 42
Biểu diễn tập hợp
Cho một số lượng nhỏ (n 30) phần tử
Gán nhãn bởi các số nguyên 0, 1, . . . , n 1
Biểu diễn tập hợp các phần tử y bởi một biến nguyên 32-bit
Phần thử thứ i trong tập được biểu diễn bởi số nguyên x nếu bit thứ
i của x 1
dụ:
I
Cho tập hợp {0, 3, 4}
I
int x = (1 < <0) | (1 < <3) | (1 < <4);
16 / 42
Biểu diễn tập hợp
Tập rỗng:
0
Tập một phần tử:
1<< i
Tập trụ (nghĩa tất cả các phần tử):
(1< <n ) -1
Hợp hai tập:
x|y
Giao hai tập:
x&y
Phần một tập:
~x & ((1 < < n ) -1)
17 / 42
| 1/1245

Preview text:

Cấu trúc dữ liệu và Thư viện THUẬT TOÁN ỨNG DỤNG Đỗ Phan Thuận thuandp.sinhvien@gmail.com
Bộ môn Khoa Học Máy Tính, Viện CNTT & TT,
Trường Đại Học Bách Khoa Hà Nội. Ngày 15 tháng 10 năm 2019 1 / 42 1
Các kiểu dữ liệu cơ bản 2 Số nguyên lớn 3
Thư viện CTDL và Thuật toán Dequeue Sắp xếp và tìm kiếm 4
Biểu diễn tập hợp bằng Bitmask 5
Một số ứng dụng của CTDL 6 Cấu trúc dữ liệu mở 7 Biểu diễn đồ thị 2 / 42 1
Các kiểu dữ liệu cơ bản 2 Số nguyên lớn 3
Thư viện CTDL và Thuật toán Dequeue Sắp xếp và tìm kiếm 4
Biểu diễn tập hợp bằng Bitmask 5
Một số ứng dụng của CTDL 6 Cấu trúc dữ liệu mở 7 Biểu diễn đồ thị 3 / 42
Các kiểu dữ liệu cơ bản
Các kiểu dữ liệu phải biết:
I bool: biến bun (boolean) (true/false)
I char: biến nguyên 8-bit (thường được sử dụng để biểu diễn các ký tự ASCII) I short: biến nguyên 16-bit I int: biến nguyên 32-bit
I long long: biến nguyên 64-bit I float: biến thực 32-bit I double: biến thực 64-bit
I long double: biến thực 128-bit I string: biến xâu ký tự 3 / 42
Các kiểu dữ liệu cơ bản Loại Số Byte Giá trị nhỏ nhất Giá trị lớn nhất bool 1 char 1 -128 127 short 2 -32768 32767 int/long 4 -2148364748 2147483647 long long 8 -9223372036854775808 9223372036854775807 n −28n−1 28n−1 − 1 Loại Số Byte Giá trị nhỏ nhất Giá trị lớn nhất unsigned char 1 0 255 unsigned short 2 0 65535 unsigned int 4 0 4294967295 unsigned long long 8 0 18446744073709551615 n 0 28n − 1 Loại Số Byte Giá trị nhỏ nhất Giá trị lớn nhất float 4 ≈ −3.4 × 10−38 ≈ 3.4 × 10−38 ≈ 7 chữ số double 8 ≈ −1.7 × 10−308 ≈ 1.7 × 10−308 ≈ 14 chữ số 4 / 42 1
Các kiểu dữ liệu cơ bản 2 Số nguyên lớn 3
Thư viện CTDL và Thuật toán Dequeue Sắp xếp và tìm kiếm 4
Biểu diễn tập hợp bằng Bitmask 5
Một số ứng dụng của CTDL 6 Cấu trúc dữ liệu mở 7 Biểu diễn đồ thị 5 / 42 Số nguyên lớn
Làm thế nào để tính toán với số nguyên cực lớn, nghĩa là không thể
lưu trữ bằng kiểu long long
Ý tưởng đơn giản: Lưu số nguyên dưới dạng string
Tuy nhiên làm thế nào để tính toán số học giữa hai số nguyên?
Có thể dùng thuật toán giống như phương pháp tính bậc tiểu học:
tính từng chữ số, từng phần, có lưu phần nhớ 6 / 42
Bài toán ví dụ: Integer Inquiry
http://uva.onlinejudge.org/external/4/424.html 7 / 42 1
Các kiểu dữ liệu cơ bản 2 Số nguyên lớn 3
Thư viện CTDL và Thuật toán Dequeue Sắp xếp và tìm kiếm 4
Biểu diễn tập hợp bằng Bitmask 5
Một số ứng dụng của CTDL 6 Cấu trúc dữ liệu mở 7 Biểu diễn đồ thị 8 / 42
Tầm quan trọng của cấu trúc dữ liệu
Nhiều khi dữ liệu cần được biểu diễn theo cách thuận lợi cho I Truy vấn hiệu quả I Chèn hiệu quả I Xóa hiệu quả I Cập nhật hiệu quả
Nhiều khi dữ liệu cần được biểu diễn theo cách tốt hơn nữa
I Làm thế nào để biểu diễn số nguyên lớn?
I Làm thế nào để biểu diễn đồ thị?
Các cấu trúc dữ liệu giúp chúng ta thực hiện được những điều này 9 / 42 - int arr[10] - vector - list - stack - queue - priority_queue - deque - set
- map, sử dụng cây cân bằng đỏ đen
Thông thường nên sử dụng thư viện chuẩn
I Gần như chắc chắn chạy nhanh và không lỗi
I Giảm bớt việc viết code
Nhiều khi vẫn cần tự viết code thay vì dùng thư viện chuẩn
I Khi muốn kiểm soát linh hoạt
I Khi muốn tùy biến/hiệu chỉnh cấu trúc dữ liệu
Các cấu trúc dữ liệu thông dụng Mảng tĩnh Mảng động Danh sách liên kết Ngăn xếp Hàng đợi Hàng đợi ưu tiên Hàng đợi hai đầu Tập hợp Ánh xạ 10 / 42
Thông thường nên sử dụng thư viện chuẩn
I Gần như chắc chắn chạy nhanh và không lỗi
I Giảm bớt việc viết code
Nhiều khi vẫn cần tự viết code thay vì dùng thư viện chuẩn
I Khi muốn kiểm soát linh hoạt
I Khi muốn tùy biến/hiệu chỉnh cấu trúc dữ liệu
Các cấu trúc dữ liệu thông dụng Mảng tĩnh - int arr[10] Mảng động - vector Danh sách liên kết - list Ngăn xếp - stack Hàng đợi - queue
Hàng đợi ưu tiên - priority_queue
Hàng đợi hai đầu - deque Tập hợp - set
Ánh xạ - map, sử dụng cây cân bằng đỏ đen 10 / 42
Các cấu trúc dữ liệu thông dụng Mảng tĩnh - int arr[10] Mảng động - vector Danh sách liên kết - list Ngăn xếp - stack Hàng đợi - queue
Hàng đợi ưu tiên - priority_queue
Hàng đợi hai đầu - deque Tập hợp - set
Ánh xạ - map, sử dụng cây cân bằng đỏ đen
Thông thường nên sử dụng thư viện chuẩn
I Gần như chắc chắn chạy nhanh và không lỗi
I Giảm bớt việc viết code
Nhiều khi vẫn cần tự viết code thay vì dùng thư viện chuẩn
I Khi muốn kiểm soát linh hoạt
I Khi muốn tùy biến/hiệu chỉnh cấu trúc dữ liệu 10 / 42
Deque - Hàng đợi hai đầu
Deque=Double-Ended Queue: là CTDL có tính chất của cả Stack và
Queue, nghĩa là cho phép thêm và xóa ở cả hai đầu
# i n c l u d e < deque >
deque < string > m y D e q u e ;
hỗ trợ tất cả các phương thức của kiểu vector và list bao gồm cả chỉ số và con trỏ (iterator)
I size() trả về kích thước của deque
I front() trả về phần tử đầu tiên của deque
I back() trả về phần tử cuối cùng của deque
I push_front() thêm phần tử mới vào đầu của deque
I push_end() thêm phần tử mới vào cuối của deque
I pop_front() xóa phần tử đầu của deque
I pop_end() xóa phần tử cuối của deque 11 / 42
Deque - Kiểm tra chuỗi Palindrome 12 / 42
Tùy biến kiểu priority_queue
Trong nhiều trường hợp không thể dùng trực tiếp kiểu priority_queue mà
cần tùy biến lại để cài đặt thuật toán. Ví dụ:
c l a s s P l a n e { // tuy b i e n p r i o r i t y q u e u e min p u b l i c : int f u e l
p u b l i c : P l a n e ( int vQ ) { ( * t h i s ). f u e l = f u e l ;}
f r i e n d o s t r e a m & o p e r a t o r < <( o s t r e a m & os , c o n s t P l a n e & p ){
os < < p . fuel < < e n d l ; r e t u r n os ; }
b o o l o p e r a t o r >( c o n s t L a b V e r & p ) c o n s t {
r e t u r n fuel > p . f u e l ; } };
t y p e d e f p r i o r i t y _ q u e u e < Plane , vector < Plane > , greater < Plane > > P Q P l a n e ; P Q P l a n e PQ ; int m a i n (){ vector < Plane > vP ;
vP . p u s h _ b a c k ( P l a n e ( 4 ) ) ; vP . p u s h _ b a c k ( P l a n e ( 7 ) ) ;
vP . p u s h _ b a c k ( P l a n e ( 3 ) ) ; vP . p u s h _ b a c k ( P l a n e ( 9 ) ) ;
P Q P l a n e PQ ( vP . b e g i n () , vP . end ( ) ) ;
w h i l e (! PQ . e m p t y ( ) ) { cout < < PQ . top (); PQ . pop ( ) ; } r e t u r n 0; } 13 / 42 Sắp xếp và Tìm kiếm
Các toán tử thông dụng nhất:
I Sắp xếp một mảng - sort(arr.begin(), arr.end())
I Tìm kiếm trên một mảng chưa sắp xếp - find(arr.begin(), arr.end(), x)
I Tìm kiếm trên một mảng đã sắp xếp - lower_bound(arr.begin(), arr.end(), x)
Thông thường nên sử dụng thư viện chuẩn
Có lúc cần phiên bản khác của tìm kiếm nhị phân nhưng bình thường lower_bound là đủ
hơn 90% sinh viên tự lập trình sai tìm kiếm nhị phân 14 / 42 1
Các kiểu dữ liệu cơ bản 2 Số nguyên lớn 3
Thư viện CTDL và Thuật toán Dequeue Sắp xếp và tìm kiếm 4
Biểu diễn tập hợp bằng Bitmask 5
Một số ứng dụng của CTDL 6 Cấu trúc dữ liệu mở 7 Biểu diễn đồ thị 15 / 42 Biểu diễn tập hợp
Cho một số lượng nhỏ (n ≤ 30) phần tử
Gán nhãn bởi các số nguyên 0, 1, . . . , n − 1
Biểu diễn tập hợp các phần tử này bởi một biến nguyên 32-bit
Phần thử thứ i trong tập được biểu diễn bởi số nguyên x nếu bit thứ i của x là 1 Ví dụ: I Cho tập hợp {0, 3, 4} I
int x = (1 < <0) | (1 < <3) | (1 < <4); 16 / 42 Biểu diễn tập hợp Tập rỗng: 0 Tập có một phần tử: 1 < < i
Tập vũ trụ (nghĩa là tất cả các phần tử): (1 < < n ) -1 Hợp hai tập: x | y Giao hai tập: x & y Phần bù một tập:
~ x & ((1 < < n ) -1) 17 / 42