1. Trang chủ
  2. » Giáo án - Bài giảng

ÔN THI OLYMPIC CẤP KHOA 2012 ĐH Mở

47 524 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 47
Dung lượng 770,37 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

ÔN THI OLYMPIC CẤP KHOA 2012 Tập Tin Một Số Phương Thức và Toán Tử Thao Tác Đọc Định Nghĩa Đệ Qui y Một định nghĩa đệ qui phải có hai phần: 1. Phần neo hay cơ sở: Được định nghĩa không đệ qui. 2. Phần qui nạp hay đệ qui: Được định nghĩa dựa trên giá trị đã được định nghĩa trước đó. Thuật Toán Quay Lui

Trang 1

ÔN THI OLYMPIC CẤP KHOA 2012

Trang 2

ThS.GVC Tô Oai Hùng 2

Nội Dung

y Tập tin: Mở, tạo mới, đọc/ghi, đóng tập tin.

y Đệ qui: Định nghĩa và xây dựng hàm đệ qui, backtracking.

y Bài tập.

Trang 3

Tập Tin

y Các bước thao tác trên tập tin:

1 Thêm chỉ dẫn #include <fstream.h>.

2 Đọc hoặc gán tên tập tin vào biến kiểu

chuỗi, ví dụ là fileName.

3 Tạo các đối tượng iFile/oFile thuộc

lớp ifstream/ofstream tùy theo tập tin dùng để đọc hay ghi (nếu đọc và ghi thì phải thêm tham số thứ 2 của phương thức open()).

4 Kết nối chương trình với tập tin fileName thông qua các đối tượng này bằng phương thức open().

Trang 5

Lớp ifstream & ofstream

y Khi thao tác với tập tin, các luồng không được tạo tự động mà phải mở luồng:

- Tạo kết nối giữa chương trình trong bộ nhớ với tập tin trên đĩa bằng cách sử dụng phương thức open() của các đối tượng thuộc lớp ifstream và ofstream.

Trang 6

ThS.GVC Tô Oai Hùng 6

Lớp ifstream & ofstream

y Khai báo luồng tập tin để đọc:

Trang 7

y >> Toán tử, đọc giá trị đơn vào biến

y getline() Đọc dòng văn bản vào chuỗi

ký tự.

y get() Đọc một hay nhiều ký tự.

y << Toán tử, ghi giá trị đến tập tin.

y eof() Trả về true nếu đến cuối tập tin.

Trang 9

Phương Thức open()

y Khi tập tin được mở để ghi, con trỏ tập tin

sẽ được đặt tại ký hiệu kết thúc tập tin.

Trang 11

Mở Tập Tin Không Dùng open()

y Có thể mở tập tin lúc khai báo đối tượng:

ifstream iFile("pressure.in");

ofstream oFile("pressure.out");

Trang 12

ThS.GVC Tô Oai Hùng 12

Phương Thức is_open()

y Thao tác mở tập tin phải luôn được kiểm tra

có thành công không bằng is_open():

iFile.open(fileName);

assert(iFile.is_open());

Hoặc oFile.open(fileName);

assert(oFile.is_open());

Có thể viết:

if(!iFile) { cerr << “File not found!\n“;

exit(1); }

Trang 13

Thao Tác Đọc

y Chúng ta đã sử dụng toán tử >>:

cin >> x;

để nhập giá trị từ bàn phím vào biến.

y C++ sử dụng cùng toán tử này để nhập giá trị vào biến từ đối tượng của ifstream:

iFile >> x;

y Sau mỗi lần đọc, con trỏ tập tin di chuyển đến phần tử kế tiếp

Trang 14

- Đọc cho đến khi gặp ký tự ‘\n’.

- Ký tự ‘\n’ được bỏ đi.

Trang 15

Trong đó: iFile là đối tượng lớp ifstream.

- Dạng (1) và (2): Đọc một ký tự từ luồng nhập (dù là ký tự trắng).

- Dạng (3): Giống như cin.getline()

Trang 17

Thao Tác Ghi

y Tương tự như toán tử >> được sử dụng với ifstream, toán tử << được sử dụng với ofstream để xuất dữ liệu từ luồng này.

outStream<<"\n > There were a total of“

<< count << "values.";

Sau mỗi lần ghi, con trỏ tập tin di chuyển về

Trang 18

ThS.GVC Tô Oai Hùng 18

Phương Thức close()

y Luồng tập tin sẽ không được kết nối khi:

- Chương trình thoát khỏi tầm vực của đối tượng fstream (mặc định).

- Hoặc khi phương thức close()được thực thi.

y Trong lập trình nên đóng tập tin bằng phương thức close() khi không còn dùng đến.

y Bài tập: Lấy ví dụ về đọc nội dung tập tin văn bản vào mảng một chiều.

Trang 19

Định Nghĩa Đệ Qui

chính khái niệm đó.

y Ví dụ 1: Định nghĩa đệ qui “Số tự nhiên”:

- 0 là một số tự nhiên.

- n là số tự nhiên nếu n - 1 là số tự nhiên.

y Ví dụ 2: Định nghĩa đệ qui giai thừa (ký hiệu

là n!) của số nguyên n không âm.

Trang 20

ThS.GVC Tô Oai Hùng 20

Định Nghĩa Đệ Qui

y Một định nghĩa đệ qui phải có hai phần:

1 Phần neo hay cơ sở: Được định nghĩa

không đệ qui.

2 Phần qui nạp hay đệ qui: Được định

nghĩa dựa trên giá trị đã được định nghĩa trước đó.

Trang 21

Hàm Đệ Qui

y Để viết được hàm đệ qui, chúng ta tìm

cách định nghĩa bài toán dạng đệ qui và sau đó viết hàm đệ qui từ định nghĩa trên:

- Đầu tiên tìm phần cơ sở (không đệ qui).

- Kế đến tìm phần đệ qui sao cho những lần đệ qui tiếp theo phải hội tụ về phần

Trang 22

ThS.GVC Tô Oai Hùng 22

Hàm Đệ Qui

y Ví dụ hàm đệ qui:

int factorial(int n) {

Trang 23

Sự Thực Thi Của Hàm Đệ Qui

y Quan sát các lời gọi đệ qui khi n = 4:

Trang 24

ThS.GVC Tô Oai Hùng 24

Sự Thực Thi Của Hàm Đệ Qui

Lời gọi factorial(n-1) cuối cùng, khi này là factorial(0) sẽ làm cho câu lệnh ở phần neo được thực thi Không còn lời gọi

đệ qui nào khác.

Trang 25

Sự Thực Thi Của Hàm Đệ Qui

y Bây giờ những giá trị đã tính được trả về:

1 2

24

Trang 26

ThS.GVC Tô Oai Hùng 26

Các Loại Đệ Qui

1 Đệ qui tuyến tính (Linear recursion): Mỗi

lần hàm thực thi chỉ gọi đệ qui một lần.

Ví dụ 1: Tính n!.

int factorial(int n) {

qui (tuyến tính) mySqrt() như sau: Để tính

Trang 27

Các Loại Đệ Qui

giá trị gần đúng với căn bậc hai của một số

dương bất kỳ a được thực hiện như sau: Lấy

số dương xấp xỉ khởi đầu x và tìm số xấp xỉ

mới bằng cách tính trung bình của x và a/x,

đó là (x + a/x)/2 Lặp lại quá trình này với x

được thay bằng giá trị xấp xỉ mới cho đến

khi hiệu giữa x và a/x nhỏ hơn hay bằng độ

chính xác khá bé cho trước.

2 Đệ qui đuôi (Tail recursion):

- Là một dạng của đệ qui tuyến tính.

- Trong đệ qui đuôi, lời gọi đệ qui là lệnh

Trang 28

- Lưu ý: Hàm factorial() tính n! trong ví

dụ trước không phải là đệ qui đuôi Vì lời gọi đệ qui trong hàm

return n * factorial(n–1);

Trang 29

Các Loại Đệ Qui

không phải là lệnh cuối cùng mà hàm thực thi (kết quả lời gọi đệ qui phải được nhân với n).

- Bài tập: Hãy sửa lại hàm factorial()

thành hàm đệ qui đuôi.

Trang 30

return facto(n, 1);

}

Trang 31

Các Loại Đệ Qui

3 Đệ qui nhị phân (Binary recursion): Mỗi lần

hàm thực thi thì gọi đệ qui hai lần

- Ví dụ 1: Tính số tổ hợp không lặp chập k

từ n phần tử (tập con k phần tử của n phần tử).

Định nghĩa đệ qui:

Trang 33

Các Loại Đệ Qui

4 Đệ qui nhánh: Mỗi lần hàm thực thi, lời gọi

đệ qui được thực hiện nhiều hơn một lần Bài toán Tháp Hà Nội là một ví dụ về đệ qui nhánh (có 3 lời gọi đệ qui).

void move(int n, char source, char

spare, char dest) { if(n == 1)

cout << "Chuyển đĩa từ " << source

<< " sang " << dest << endl;

else {

move(n-1, source, dest, spare);

move(1, source, ' ', dest);

Trang 36

ThS.GVC Tô Oai Hùng 36

6 Đệ qui hỗ tương (Mutual recursion): Các

hàm đệ qui thực hiện lời gọi lẫn nhau Một trong các ứng dụng của nó là vẽ đường Hilbert và Sierpinski:

y Ví dụ: Xác định số chẵn/lẻ.

bool is_odd(int);

Trang 37

Các Loại Đệ Qui

bool is_even(int n) {

if(n == 0)

return true;

return is_odd(n-1);

} bool is_odd(int n) {

return !is_even(n);

}

Trang 38

ThS.GVC Tô Oai Hùng 38

Các Loại Đệ Qui

7 Đệ qui chồng/lồng (Implicated/nested

gọi đệ qui Ví dụ, tính hàm Ackermann cho

mọi số nguyên không âm m, n.

int ackerman(int m, int n)

{

if(m == 0)

return n + 1;

Trang 40

ThS.GVC Tô Oai Hùng 40

Thuật Toán Quay Lui

y Thuật toán quay lui (backtracking) được

sử dụng trong phương pháp "thử và sai" Nét đặc trưng của thuật toán này là để có được lời giải, ta phải đi từng bước bằng phép thử Giả sử bài toán có n trường hợp

x 1 , x 2 , , x n và giả sử đã chúng ta đã xây dựng xong i - 1 trường hợp (x 1 , x 2 , , x i-

1 ), bây giờ đang xây dựng trường hợp thứ

i (x i ):

- Nếu tồn tại một khả năng chấp nhận được, chọn khả năng này và nếu i = n

Trang 41

Thuật Toán Quay Lui

thì x i là một lời giải Ngược lại nếu i < n thì

ghi nhớ trường hợp này và tiến hành xây dựng trường hợp kế tiếp i + 1.

- Nếu không tồn tại khả năng nào cho x i thì

xoá ghi nhớ và lùi lại bước trước đó x i - 2

để thử các khả năng còn lại cho x i - 1.

y Thuật toán quay lui có dạng như sau:

void Try(int i)

{

if(<x là trường hợp kết thúc>)// i > n

Trang 42

ThS.GVC Tô Oai Hùng 42

Thuật Toán Quay Lui

else

for(<j thuộc tập các lựa chọn>)

if(<khả năng thứ j chọn được>) {

<xác định x i theo khả năng j>

<ghi nhớ trạng thái mới>

Try(i + 1) // thử bước kế tiếp

<xoá bỏ ghi nhớ, về trạng thái cũ > }

}

Trang 43

Thuật Toán Quay Lui

y Để minh họa cho thuật toán quay lui, ta xét

bài toán mã đi tuần (Knight’s tour):

Cho một bàn cờ có kích thước là n × n (5

≤ n ≤ 8) Một con mã di chuyển theo luật cờ

vua được đặt trong một ô với tọa độ ban đầu

là (x 0 , y 0 ) Hãy tìm một đường đi với n 2 - 1

bước đi còn lại sao cho mọi ô trên bàn cờ

đều được con mã nhảy đến đúng một lần Ví

dụ, với n = 5, tọa độ ban đầu là (0, 0) thì một

trong các lời giải là:

Trang 44

ThS.GVC Tô Oai Hùng 44

Thuật Toán Quay Lui

Trang 45

Thuật Toán Quay Lui

for(<j thuộc tập các lựa chọn>)

// 0 ≤ j < 8 (có tối đa 8 vị trí mới) {

u = x + dx[j];

v = y + dy[j];

if(<có khả năng thứ j>) // ((u >= 0 && u < n) &&

Trang 46

<xoá bỏ ghi nhớ, trở về trạng thái cũ>

//(board[u][v] = 0;

// x = x - dx[j];

// y = y - dy[j];) }

}

Trang 47

Thuật Toán Quay Lui

y Bài tập

Ngày đăng: 08/06/2017, 17:06

TỪ KHÓA LIÊN QUAN

w