1. Trang chủ
  2. » Thể loại khác

TÀI LIỆU ĐẠI HỌC - godautre PPLT-Chuong 2

120 245 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 120
Dung lượng 2,34 MB

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

Nội dung

TÀI LIỆU ĐẠI HỌC - godautre PPLT-Chuong 2 tài liệu, giáo án, bài giảng , luận văn, luận án, đồ án, bài tập lớn về tất cả...

Trang 1

Chương 2 Phương pháp lập trình hàm và

ứng dụng trong NET

Trang 2

• Mô hình tính toán dựa trên các khái niệm toán học của hàm

• Mỗi hàm có thể không đối số hoặc nhiều đối số Kết quả của hàm là một giá trị xác định hoặc dự báo

• Ngôn ngữ lập trình hàm: FP, Haskell, Gopher…

1 Lập trình hàm

Trang 3

• Số tự nhiên: Toán học: 1,2…

Khoa học tính toán: 0,1,2…

• Ví dụ về một hàm đơn giản: Hàm tính giai thừa:

fact(n) = 1 x 2 x 3… x n với fact(0) =1

• Có thể được viết theo các dạng:

• Dễ thấy rằng, định nghĩa sau là tương đương với 2 định nghĩa trước (có thể chứng minh bằng quy nạp)

2 Định nghĩa của hàm

Trang 4

3 Nhìn qua về lập trình cho hàm

trong Gopher

• Hàm fact(n) với định nghĩa:

Có thể được lập trình với cách cách khác nhau trong Gopher

Trang 5

1 Thông qua biểu thức

-Dòng 1: Xác định kiểu cho hàm fact1 theo cú pháp object :: type

fact1 được định nghĩa như là một hàm (ký hiệu ->) với một tham

số có kiểu Int (thứ nhất) và kiểu trả lại của hàm là Int (thứ hai) (Gopher không định nghĩa tập tự nhiên nên tạm sử dụng kiểu Int)-Dòng 2: Khai báo nội dung của hàm fact1, nó có dạng:

fname params = body

Trong đó: fname: Tên của hàm

params: các tham số của hàm (có thể không có) body : một biểu thức xác định giá trị của hàm.

ví dụ trên là biểu thức if – then - else

Trang 10

Ví dụ về file nguồn facts.gs

Trang 11

Một số lệnh thông dịch

Trang 13

Ví dụ về thực hiện tính biểu thức và hàm thư viện

trên dòng lệnh

Khoảng thời gian cần tính và

số ô nhớ được sử dụng

Trang 15

Ví dụ về việc nộp và thực hiện các hàm trong

chương trình

• Nộp file chương trình facts.gs nói trên

Trang 16

• Liệt kê tên hàm trong chương trình

• Gọi thực hiện các hàm trong chương trình

Trang 18

5.1 Các kiểu định nghĩa sẵn (built-in types)

Giá trị: True, False

Toán tử : && (and) || (or) và not

5 Cơ bản về Gopher

Trang 19

-Bao trong cặp dấu nháy đơn ‘ : ‘a’, ‘A’

- Kí tự escape : ‘\n’ , ‘\t’ , ‘\\’ , ‘\’’

- Viết dụng mã : ‘\65’ , ‘\x41’ đều cho ‘A’

Trang 20

- Nếu t1 và t2 là các kiểu thì tham số kiểu là t1 và hàm có kiểu là t2

- Tên hàm và biến bắt đầu bởi một chữ cái (a z) thường, sau đó có thể là chử cái (hoa, thường), chử số, dấu nháy đơn (‘), dấu gạch dưới (_)

- Hàm có thể có nhiều tham số Ví dụ hàm cộng 2 số nguyên:

f x y = x +y ( add x y)

được hiểu như là : f x + y = (f x) + y

Vì vậy tham số được khai báo:

Hoặc

Trang 21

 Kiểu danh sách là kiểu có cấu trúc đầu tiên của Gopher, nó là một chuổi các phần tử cũng kiểu giá trị.

 Khai báo [t] là khai báo kiểu danh sách có các phẩn tử có giá trị kiểu t

Ví dụ [Int]

 Một danh sách có thể rỗng Được ký hiệu []

 Một danh sách khác rỗng có một phần tử đầu danh sách (head element)

và phần đuôi của danh sách (tail)

 Toán tử : (dấu hai chấm) biểu diễn phần tử đầu và phần đuôi của danh sách Nó có dạng head:tail

Trang 22

• Có 2 hàm thực hiện trên kiểu danh sách là head và tail:

Ví dụ: head [5,3,2] cho lại 5 tail [5,3,2] cho danh sách [3,2]

Trang 23

• Là kiểu đã được định nghĩ như là mảng (danh sách) các ký tự:

• Hằng chuổi có thể được viết các dạng khác nhau:

• Vì là danh sách nên có thể áp dụng các hàm head và tail:

Trang 24

Ví dụ về hàm tính độ dài chuổi (len)

Hàm thực hiện như sau:

Có thể mở rộng hàm len để tính số phần

tử của một danh sách với:

len :: [a] -> Int

Trang 25

- t1, t2,…, tn là các kiểu (có thể khác nhau)

- Không giống như list, tuple có các phần tử không nhất thiết là

cùng kiểu và số phần tử của tuple là cố định Nó tương tự như kiểu Record trong Turbo – Pascal

- Ví dụ về tuple:

Trang 26

5.2 Lập trình với list

• Tổng của một list (sumlist)

- Cho danh sách gồm các phần tử nguyên v1, v2, v3, v4, … ,vn

- Tính tổng S = v1+ v2 + v3+ … + vn

- Xây dựng hàm sumlist như sau:

- Có thể thay dòng thứ 3 bởi:

Trang 27

• Hàm tính độ dài của một list (length’)

Trong hàm này, ký hiệu (_) được hiểu như là “không quan tâm” đến giá trị của phần tử head

Trang 28

• Bỏ đi các phần tử trùng lặp trong list

Để ý rằng, dòng thứ 2 chỉ thực hiện khi danh sách có không ít hơn 2 phần tử

Trang 29

• Một số mẫu khác

Dưói đây là một số mẫu tham số, đối số tương ứng và kết quả của việc thử

Trang 30

5.3 Các toán tử infix

Các toán tử infix, infixl, infixr được sử dụng để định nghĩa thứ tự thực hiện các toán tử trong biểu thức

- infix : tự do

- infixl : từ trái sang phải

- infixr : từ phải sanf trái

Ví dụ về các toán tử infix chuẩn:

Trang 31

5.4 Các kiểu đệ quy

• Nối danh sách (toán tử ++)

- Tức là nối danh sách thứ hai vào sau danh sách thứ nhất để được một danh sách

- Hàm nối 2 danh sách được ký hiệu theo kiểu toán tử ++

- Đặt infix mức 5 cho toán tử ++ (mở rộng thêm infixr 5):

infixr 5 ++

- Định nghĩa toán tử ++

Trang 32

Ví dụ thực hiện toán tử ++

Trang 34

• Đảo các phẩn tử của list (rev)

Trong đó toán tử ++ chính là toán tử nối chuổi ở trên

Ví dụ:

Trang 36

• Đảo với đệ quy phần đuôi của list

Trang 37

• Các định nghĩa cục bộ (let và where)

let

Let thường được sử dụng trong các tập định nghĩa lồng nhau Nó có

dạng:

Let được sử dụng bất kỳ ở đâu xuất hiện một biểu thức

Ví dụ: Hàm f sau đây lập một danh sách mà mỗi phần tử là bình phương của danh sách tăng từ 1 (1,2,3…)

Trang 38

 square là hàm một biến

 one là một hàm không tham số (nó là một hằng = 1)

 (y: ys) biểu thị một mẫu đối sánh của đối số xs của hàm f

 Tham chiếu y hoặc ys của đối số xs của f có thể gây lỗi khi xs là rỗng

 Các định nghĩa cục bộ square, one, y và ys có phạm vi sử dụng trong

biểu thức sau in

 Các định nghĩa cục bộ có thể truy xuất các thành phần thuộc phạm vi của nó (outer) Chẳng hạn: định nghĩa (y:ys) truy xuất xs

 Các định nghĩa cục bộ có thể đệ quy và gọi mỗi định nghĩa khác

 Mệnh đề let trình diễn theo dạng bottom-up Nó xác định các thành phần trước khi được sử dụng

Trang 39

-Tương tự như let nhưng theo kiểu top-down

- where sử dụng linh hoạt hơn let Nó cho phép định nghĩa các thành phần trong các mệnh đề trong khi let chỉ định nghĩa các thành phần

trong một biểu thức (sau in)

- Ví dụ:

Trong ví dụ này where định nghĩa cho các thành phần trong cả 3 mệnh

đề Lưu ý rằng, where được bắt đầu cùng cột với (=)

Trang 40

Một ví dụ sử dụng định nghĩa cục bộ: Số Fibonacci

Số Fibonacci: f(0) = 0

f(1) = 1

f(n+2) = f(n) + f(n+1)

Định nghĩa hàm fib theo công thức trên:

Trong định nghĩa trên, hàm fib sử dụng n+2 mẫu để đối sánh các số

tự nhiên >=2

Trang 41

Định nghĩa sau đây được coi là có hiệu suất cao hơn khi sử dụng đệ quy với việc cộng 2 số:

Trang 43

• Ngắt một list (take và drop)

take và drop là hai toán tử chuẩn

take n xs : cho lại n phần tử đầu tiên của danh sách xs Nó được định

nghĩa như là:

drop n xs : bỏ đi n phần tử đầu tiên của danh sách xs Nó được định

nghĩa như là:

Ví dụ:

Trang 44

• Liên hợp list (zip)

zip là toán tử chuẩn, cho phép hợp hai danh sách thành một danh

sách theo kiểu ghép cặp các phần tử tương ứng

Ví dụ:

zip được định nghĩa như là zip’ dưới đây:

Trang 45

5.6 Xây dựng tập số hữu tỷ

• Số hữu tỷ

Toán học: số hữu tỷ được định nghĩa như là: x/y với y<>0Gopher : Định nghĩa như là một tuple:

Type Rat = (Int, Int)

Ví dụ: (1,7), (-1,-7), (3,21) đều biểu diễn số 1/7

Trang 46

• Chuẩn hoá số hữu tỷ

- Chuyển (a,b) thành (x,y) trong đó x,y là nguyên tố cùng nhau

- Quy ước (0,y) = (0,1)

- Hàm chuẩn hoá số hữu tỷ:

Trang 47

Việc xây dựng hàm normRat dựa vào các hàm:

signum: hàm chuẩn lấy dấu của một số -1 (âm) , 0 (không), 1 (dương)

Nó được định nghĩa như là:

a được khai báo là một đối tượng thuộc lớp Num và lớp Ord

gcd: hàm chuẩn cho lại ước số chung lớn nhất Nó được định nghĩa như

là:

abs: hàm chuẩn cho lại trị tuyệt đối của một số

error: hàm chuẩn hiển thị thông báo lỗi lên màn hình

showRat: hàm hiển thị số hữu tỷ lên màn hình (xem sau)

Trang 48

• Các phép toán trên số hữu tỷ

Trang 49

• Hiển thị số hữu tỷ

Trong đó hàm show là một hàm chuẩn Nó convert một số

nguyên thành dạng chuổi

Trang 50

6 Các hàm bậc cao6.1 Hàm map

Xét hai hàm sau đây:

Bình phương mỗi phần tử trong list:

Độ dài mỗi list con trong list:

Trang 51

Hàm map cho phép thực hiện một hàm f lên mỗi phần tử của một

danh sách Nó được định nghĩa như là:

Nếu áp dụng hàm map cho 2 hàm ví dụ trên, ta có:

Trang 52

6.2 Hàm filter

Xét hai hàm sau đây:

Hàm cho lại một list các số chẳn từ một list

Hàm cho lại một list bằng cách gấp đôi phần tử dương của một list

Trang 53

Hàm chuẩn filter với một hàm điều kiện p (kiểu a->Bool) và một danh sách kiểu [a] cho lại một danh dách gồm các phần tử trong danh sách [a] thỏa hàm điều kiện p

Nó được định nghĩa như là:

Áp dụng hàm filter, các hàm trên có thể định nghĩa lại như sau:

Trang 54

6.3 Các hàm Fold

Xét hai hàm sau đây:

Hàm nối các chuổi thành một chuổi

Hàm cho lại tổng các phần tử trong list

Trang 55

Áp dụng hàm foldr , các hàm trên được định nghĩa như sau:

Trong đó: f là một toán tử nhị phân có dạng (a->b->b) Foldr thực hiện kiểu như:

Hàm foldr được định nghĩa như sau:

Hàm foldr

Áp dụng khác:

Trang 56

Hàm foldl

Nó thực hiện kiểu như:

Ví dụ áp dụng:

Trang 57

6.4 Tính bộ phận

Xét hai hàm sau:

Cả hai đêu cho cùng kết quả nhưng khác nhau về đối số:

add: đối số là một 2-tiple và cho lại một Int

add’: đối số là một Int và cho lại một hàm (Int->Int)

Do đó:

add 3  Lỗi

add’ 3  được hiểu là gán 3 cho đối số của nó ((add’ 3) 4) -> gán x, y với 3 và 4 và được 3+4 Tức:

Trang 58

Hàm add’ định nghĩa như trên là tương tự như hàm chuẩn (+) (toán tử +)

Khi viết: (+) 3 có thể hiểu “3 là cộng với…”

Các toán tử khác như (<), (*) cũng tương tự

Ví dụ:

Chú ý rằng: (*) 2 được hiểu là 2 nhân với…

(<) 0 được hiểu là 0 là bé hơn…

Trang 60

Ví dụ: Tăng đối số lên 1

Kiểm tra một số dươngHàm chia đôi

Hàm nghịch đảo

lập phương các phần tử

Trang 62

Ví dụ 2: Hàm nhân đôi các phần tử dương trong danh sách

Hàm count có 2 tham số: một số nguyên n và một danh sách các danh sách Hàm cho lại số danh sách có độ dài là n

Ví dụ 1: Hàm cho lại số danh sách có độ dài là n

Có thể viết lại:

Trang 63

Ví dụ 3: Các hàm cho phần tử cuối và phần khởi đầu danh sách (tức trừ phần tử cuối)

Có thể viết lại:

Ví dụ 4: Các hàm khác

Trang 65

Tương tự có cho các hàm có nhiều tham số Chẳng hạn

Biểu thức (\x y -> (x+y)/2)

Biểu thị hàm không định tên với 2 đối số và kết quả trả lại là trung bình công của 2 đối số

Ví dụ khác:

Hàm không tên (\n _ -> n+1) với đối số đầu là n, đối số thứ 2 là

bất kỳ, cho lại một giá trị bằng cách tăng n lên 1

Trang 66

6.8 Thêm các toán tử ngắt danh sách

Ngoài toán tử chuẩn take và drop, còn có các toán tử span, break, takeWhile, dropWhile, takeUntil, dropUntil

Trang 67

6.8 Thêm các toán tử liên hợp danh sách

Trang 68

6.9 Bổ sung các toán tử quan hệ cho tập số hữu tỷ

Trang 69

7 Các vấn đề khác về danh sách

7.1 Chuổi

Một chuổi số học là một chuổi của các phần tử kiểu liệt kê (tức thuộc lớp Enum) Các kiểu như Int, Float, Char… thuộc Enum

• [m n] dẫn suất một ds các phần tử từ m đến n theo bước 1

Dẫn xuất này phát sinh từ hàm chuẩn enumFromTo m n

• [m, m’ n] dẫn suất một ds các phần tử từ m’ đến n với bước m’-m

Dẫn xuất này phát sinh từ hàm chuẩn enumFromThenTo m m’ n

Trang 70

• [m ] , [m, m’…] tương tự như các trường hợp trên nhưng với ds vô

hạn

Các dẫn xuất này phát sinh từ hàm chuẩn enumFrom và enumFromThen

Một chuổi hình học là một chuổi mà các phần tử thuộc kiểu có thứ tự và

là kiểu số (nghĩa là thuộc lớp Ord và Num)

Ví dụ:

Trang 71

Ví dụ:

Trang 72

Biểu thức giá trị kiểu Bool cũng có thể được sử dụng như là một qualifier Chỉ có giá trị nào làm cho biểu thức là True mới được phát sinh cho danh sách bao hàm

Trang 73

Một số ví dụ khác:

Trang 74

Một số ví dụ áp dụng:

Ví dụ 1: Chuổi bao gồm các ký tự trống

Ví dụ 2: Kiểm tra số nguyên tố

Trang 75

Ví dụ 3: Bình phương của các số nguyên tố

Hàm sqPrimes sau đây cho lại danh sách mà mỗi phần tử là bình phương của số nguyên tố từ m đến n:

Có thể định nghĩa khác cho hàm này:

Trang 76

Ví dụ 4: Nhân đôi các phần tử dương

Ví dụ 5: Nối một danh sách của danh sách của danh sách

Hàm này cũng có thể định nghĩa:

Trang 77

Ví dụ 6: Tìm vị trí xuất hiện trong danh sách

Tìm tất cả các vị trí

Tìm vị trí xuất hiện đầu tiên:

Trang 78

- Tên kiểu phải viết hoa chữ cái đầu

- a1, a2,…an là các biễu diễn kiểu cho n tham số của kiểu dữ liệu

- constr1, constr2…constrn là các cấu tử dữ liệu

Trang 79

Trong định nghĩa này, Grayscale ngầm định định nghĩa một hàm cấu tử dạng Int -> Color’

Cấu tử dữ liệu có thể là giá trị kiểu liên hợp

Trang 80

Hàm sau đây sẽ chuyển một danh sách vào một Set

Hàm chuẩn nub loại bỏ các phần tử double trong danh sách

Trang 81

Định nghĩa kiểu kết quả:

Trang 82

8.2 Kiểu dữ liệu đệ quy

Kiểu dữ liệu cũng có thể được định nghĩa dạng đệ quy

Ví dụ: Kiểu sau đây định nghĩa một cây nhị phân với một giá trị trêm mỗi node:

Mỗi cây có thể là empty hoặc là một Node trrong đó mỗi node gồm một giá trị kiểu a và hai cây con “trái” và “phải”

Đề nghị đọc thêm tài liệu về kiểu dữ liệu đệ quy

Trang 83

9 Lập trình hàm trong C#

(giới thiệu)

• Các ngôn ngữ lập trình của Microsoft xuất hiện nhiều kỹ thuật mới, thay đổi về cú pháp, câu lệnh

• Cách viết các đoạn mã gọn hơn, dễ quản lý hơn

• Các dòng lệnh mang tính ước lượng giá trị của một biểu thức toán học hơn là việc thi hành một dãy lệnh

• Các thay đổi trên có nguồn góc từ lập trình hàm.

9.1 Giới thiệu:

• Lập trình hàm thể hiện rõ trong C# và F#

• Mỗi phiên bản của C# (C# 1.0, 2.0, 3.0) có sự cải thiện về FP

• Việc đưa FP vào NET cho phép:

+ Người lập trình tiết kiệm được thời gian trong coding+ Dễ phát hiện lỗi

+ Khai thác được sức mạng của các bộ xử lý đa nhân

Trang 84

Func<intlist, intlist> Sort =

Biểu thức lambda

Trang 85

9.2 Lập trình hàm trong C# 2.0

Delegate (đại diện):

Từ C# 1.x, chỉ có khai báo delegate cho các hàm lớp đầu (First – class function)

IntPred predicate = new IntPred(point.Above);

Trong C# 2.0, một số kỹ thuật được bổ sung:

- Anonymous method

-Generics delegate

-Closure và Currying

Trang 86

Anonymous method:

- Anonymous method trong C# 2.0 khắc phục những nhược điểm

của “delegate” trong các phiên bản C# 1

-Nó cho phép “inline code” giúp giảm thiểu số dòng lệnh hay các

hàm không cần thiết đôi khi chỉ gọi một lần

Ví dụ: Hàm f(x,y) = x+y

delegate int Demo(int x, int y);

public static int Exec(int x, int y)

lại giá trị của hàm f

Trang 87

Generics delegate:

Trong các ngôn ngữ C, hàm f được mô tả dưới dạng: R f (D)

Trong đó: R: Kiểu trả lại của hàm, D: Kiểu tham số

Ví dụ: Với hàm lấy tổng 2 số nguyên f(x,y) = x+y

Khai báo đầu hàm:

int f(int, int)

Khai báo nội dung hàm:

int add(int x, int y) { return x + y; }

Generics delegate cho phép biến đổi về dạng mới “Func” Khi đó cú pháp trong ngôn ngữ lập trình trở thành:

Trang 88

Là khả năng các đoạn mã bên trong delegate tham chiếu đến giá trị của những biến không nằm trong phạm vi khai báo của nó

delegate int Demo(int x);

static int ClosureDemo(int x)

Kết quả trả về của hàm “ClosureDemo(1)” sẽ không phải là “1+1= 2” mà sẽ là

“100” “myClosure” sẽ không lấy giá trị “y=1” mà nó chỉ tham chiếu đến biến “y” khi cần

Do đó nó đảm bảo giá trị mới nhất luôn được sử dụng.

Trang 89

Ứng Dụng Closure giải quyết tranh chấp dữ liệu trong lập trình đa luồng:

Trong lập trình đa luồng xử lý đồng thời, người lập trình thường phải giải quyết những khó khăn khi phải dùng chung biến giữa các luồng

Ví dụ: Tìm kiếm tên trong một danh sách

Xét đoạn mã chương trình sau:

static string g_Name;

static List people = new List

{ new Person{ Name=”An”, Age=41, Salary = 500},

new Person{ Name=”Huy”, Age=26, Salary = 300},

new Person{ Name=”Thanh”, Age=30, Salary = 400}, };

static bool SearchName(Person p) { return p.Name.Equals(g_Name); }static List PersonListName(Person p) {

g_Name = p.Name;

return people.FindAll(SearchName);

}

Ngày đăng: 21/12/2017, 12:12

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w