Ngôn ngữ Perl-Chương 05-Mảng_Băm

4 241 0
Ngôn ngữ Perl-Chương 05-Mảng_Băm

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

Thông tin tài liệu

Learning Perl - Chương 5: Mảng băm 1. Mảng băm 2. Biến mảng băm 3. Biểu diễn hằng ký hiệu cho mảng băm 4. Các toán tử trên mảng băm 5. Bài tập 5.1 Mảng băm Mảng băm cũng tựa như mảng (kiểu danh sách), trong đó nó là một tập các dữ liệu vô hướng, với các phần tử riêng được chọn ra bằng một giá trị chỉ số nào đó. Không giống mảng danh sách, giá trị chỉ số của mảng băm không phải là số nguyên không âm nhỏ, mà thay vào đó là vô hướng tuỳ ý. Những vô hướng này (còn gọi là khoá) được dùng về sau để tìm kiếm các giá trị từ mảng này. Các phần tử của mảng băm không có thứ tự đặc biệt. Bạn hãy xem chúng tựa như bàn đầy những quân bài. Nửa trên của các con bài là khoá, còn nửa dưới là giá trị của chúng. Mỗi lần bạn đặt một giá trị vào trong mảng băm thì một con bài mới lại được tạo ra. Về sau khi bạn muốn sửa đổi giá trị này, bạn cho khoá, còn Perl tìm ra đúng con bài. Cho nên, thực sự, trật tự của các con bài là không quan trọng. Trong thực tế, Perl cất giữ các con bài (cặp khoá-giá trị) bên trong theo một thứ tự đặc biệt để dễ dàng tìm ra một con bài cụ thể, cho nên Perl không phải duyệt qua tất cả các cặp để tìm ra đúng con bài. Bạn không thể kiểm soát được trật tự này. 5.2 Biến mảng băm Tên biến mảng băm mà một dấu phần trăm (%) theo sau bởi một chữ cái, theo sau nữa là không hay nhiều chữ, chữ số và dấu gạch dưới. Nói cách khác, phần đi sau dấu % giống hệt cái mà chúng ta có cho tên biến vô hướng và biến mảng. Và tương tự, chẳng có quan hệ gì giữa $jerry, @jerry và %jerry cả. Thay vì tham khảo tới toàn bộ mảng băm, thông dụng hơn cả là ta tạo ra một mảng băm và truy cập vào nó bằng cách tham khảo tới các phần tử của nó. Mỗi phần tử của mảng đều là một vô hướng tách biệt, được truy cập tới bởi một chỉ mục vô hướng, gọi là khoá. Các phần tử của mảng băm %jerry vậy được tham khảo đến bằng $jerry{$key} với $key là bất kì biểu thức vô hướng nào. Ta lại chú ý rằng việc truy cập vào một phần tử của mảng ta dùng ký hiệu $ chứ không phải lả % để truy cập vào toàn bộ mảng. Giống như với mảng danh sách, bạn có thể tạo ra những phần tử mới cho mảng băm bằng việc gán cho mảng một phần tử: $jerry{"aaa"} = "bbb"; # tạo ra khoá "aaa" với giá trị "bbb" $jerry{234.5} = 456.7; # tạo ra khoá "234.5", giá trị 456.7 Hai câu lệnh này tạo ra hai phần tử trong mảng. Những tham khảo về sau tới cùng những phần tử này (dùng cùng khoá) sẽ cho lại giá trị được cất giữ. print $jerry{"aaa"}; # in "bbb" $jerry{234.5} += 3; # $jerry{234.5} giờ mang giá trị 459.7 Việc tham khảo tới một phần tử không có sẵn sẽ trả về giá trị undef, giống như với mảng danh sách hay biến vô hướng không xác định. 5.3 Biểu diễn hằng kí hiệu cho mảng băm Bạn có thể muốn truy cập vào mảng băm như một toàn thể, để hoặc khởi tạo giá trị cho nó hay sao chép nó sang mảng băm khác. Perl không thực sự có biểu diễn hằng kí hiệu cho mảng băm, cho nên thay vì thế nó tháo rời mảng ra như một danh sách. Mỗi cặp phần tử trong danh sách (mà bao giờ cũng phải có một số chẵn phần tử) đều xác định ra một khoá và giá trị tương ứng của nó. Biểu diễn tháo rời này có thể được gán vào trong mảng băm khác, mà rồi sẽ tái tạo lại cùng mảng băm. Nói cách khác: @jerry_list = %jerry; # @jerry_list nhận ("aaa", "bbb", "234.5", 456.7) %tom = @jerry_list; # tạo ra %tom giống %jerry %tom = %jerry; # cách nhanh hơn để làm cùng việc đó %smooth = ("aaa", "bbb", "234.5", 456.7); # tạo ra %smooth giống như %jerry, từ các giá trị hằng kí hiệu Trật tự của các cặp khoá-giá trị là tuỳ ý trong cách biểu diễn tháo rời này, và không thể kiểm soát được. Cho dù bạn có tráo đổi một số giá trị và tạo ra một mảng như một toàn thể thì danh sách tháo rời thu được vẫn cứ theo bất kì trật tự nào mà Perl đã tạo ra để thâm nhập hiệu quả vào các phần tử riêng. Bạn đừng bao giờ nên dựa trên bất kì trật tự đặc biệt nào. 5.4 Các toán tử trên mảng băm Sau đây là một số toán tử cho mảng băm. • 5.4.1 Toán tử keys() Toán tử keys(%tên_mảng) trả về danh sách các tất cả các khoá hiện có trong mảng băm %tên_mảng. Nói cách khác, nó tựa như các phần tử được đánh số lẻ (1, 3, 5 .) của danh sách có được sau khi tháo rời %tên_mảng thàn một mảng danh sách, và trong thực tế, cho lại chúng theo trật tự đó. Nếu không có phần tử nào trong mảng băm thì keys() trả về một danh sách rỗng. Chẳng hạn, bằng việc dùng mảng băm từ ví dụ trước: $jerry{"aaa"} = "bbb"; $jerry{234.5} = 456.7; @list = keys(%jerry); # @list = ("aaa", 234.5) hoặc (234.5, "aaa"), trật tự này ta không kiểm soát được Các dấu ngoặc là tuỳ chọn: keys %jerry cũng tương tự như keys(%jerry). foreach $key (key %jerry) { # duyệt qua danh sách các khoá của %jerry print "tại $key chúng ta có $jerry{$key}\n"; # in khoá và giá trị } Ví dụ này cũng chỉ ra rằng các phần tử mảng băm có thể chen lẫn nhau trong các xâu nháy kép. Tuy nhiên bạn không thể xen lẫn toàn bộ mảng. Trong ngữ cảnh vô hướng, toán tử keys() cho lại số các phần tử (cặp khoá-giá trị) trong mảng băm. Chẳng hạn, bạn có thể tìm ra liệu mảng băm có rỗng hay không: if (keys(%mang)) { # nếu keys() khác không: .; # mảng là khác rỗng } # . hoặc . while (keys(%mang) < 10) { .; # cứ lặp chu trình khi ta có ít hơn 10 phần tử } • 5.4.2 Toán tử values() Toán tử values(%tên_mảng) trả về một danh sách tất cả các giá trị hiện tại của %tên_mảng, theo cùng trật tự như các khoá được toán tử keys(%tên_mảng) cho lại. Như với keys(), các dấu ngoặc tròn là tuỳ chọn. Chẳng hạn: %lastname = (); # gán %lastname là rỗng $lastname("jerry"} = "flintstore"; $lastname{"tom"} = "rubble"; @lastname = values(%lastname); # lấy các giá trị #Tại điểm này @lastname chứa ("flintstore", "rubble") hoặc đảo ngược của nó • 5.4.4 Toán tử each() Nếu bạn muốn duyệt mọi phần tử của toàn bộ mảng băm, thì bạn có thể dùng keys(), duyệt xét từng khoá được cho lại và nhận giá trị tương ứng. Trong khi phương pháp này thường hay được dùng, một cách hiệu quả hơn là dùng each(%tên_mảng), toán tử này sẽ trả về cặp khoá- giá trị như một danh sách hai phần tử. Với mỗi lần thực hiện toán tử này cho cùng mảng, cặp khoá-giá trị kế tiếp sẽ được trả về, cho tới khi tất cả các phần tử đều đã được truy cập. Khi không còn cặp nào nữa thì each() trả về một danh sách rỗng. Vậy chẳng hạn, để duyệt qua toàn bộ mảng %lastname trong vhí dụ trước, hãy làm điều gì đó tựa như thế này: while (($first, $last) = each(%lastname)) { print "First name of $first is $last\n"; } Việc gán một giá trị mới cho toàn bộ mảng sẽ đặt lại từng toán tử each() trở về vị trí bắt đầu (phần tử đầu tiên). Việc bổ sung hay loại bỏ các phần tử của mảng thì rất có thể gây ra lẫn lộn each() (và có thể gây lẫn lộn cho cả bạn nữa). • 5.4.5 Toán tử delete Cho đến giờ, với điều bạn biết được, bạn có thể thêm phần tử vào mảng băm, nhưng bạn không thể loại bỏ chúng (một việc khác hơn là gán giá trị mới cho toàn bộ mảng). Perl cung cấp toán tử delete để loại bỏ các phần tử. Toán hạng của delete là một tham khảo (tựa như con trỏ trong C) đến mảng băm, hệt như nếu bạn chỉ nhìn vào một giá trị đặc biệt. Perl loại bỏ cặp khoá-giá trị khỏi mảng băm, và cho lại giá trị của phần tử bị xoá. Chẳng hạn: %jerry = ("aaa", "bbb", 234.5, 34.56); # cho %jerry 2 phần tử delete $jerry{"aaa"}; # %jerry bây giờ chỉ còn một cặp khoá-giá trị • 5.4.6 Lát cắt mảng băm Tương tự như mảng danh sách, mảng băm có thể được 'cắt' thành từng phần nhỏ-tập hợp một số phần tử nào đó của mảng. Ví dụ, ta có thể tạo một mảng theo cách sau: $score{"fred"} = 205; $score{"barney"} = 195; $score{"dino"} = 30; Trông có vẻ không được gọn gàng cho lắm, ta có thể viết ngắn hơn như sau: ($score{"fred"}, $score{"barney"}, $score{"dino"}) = (205,195,30); Tuy nhiên ta thậm chí có thể viết ngắn hơn nữa dùng lát cắt: @score{"fred", "barney", "dino"} = (205, 195, 30); Và đây nữa, ta có thể dùng lát cắt trong xâu nháy kép: @players = ("fred", "barney", "dino"); print "scores are: @score{@players}\n"; Lát cắt cũng có thể được dùng để ghép một mảng băm con vào một mảng băm khác lớn hơn. Hãy xem ví dụ sau, mảng băm con được ưu tiên hơn: nếu có cùng một khoá tồn tại trong cả mảng băm con và mảng băm lớn thì giá trị trong mảng băm con sẽ được sử dụng: %league{keys %score} = value %score; Ở đây, mảng con %score được ghép vào mảng lớn %league. Bạn cũng có thể làm cách khác (chậm hơn): %league = (%league, %score); 5.5 Bài tập 1. Bạn hãy viết 1 chương trình đọc vào một xâu rồi in ra xâu đó cùng với giá trị tương ứng với xâu đó theo bảng sau: Xâu Giá trị red apple green leaves blue ocean 2. Bạn hãy viết 1 chương trình đọc vào một danh sác các từ, mỗi từ trên 1 dòng (quá trình nhập kết thúc khi chương trình nhận được dấu hiệu end-of-file: kết thúc file). Sau đó in ra một bảng tổng kết xem mỗi từ xuất hiện bao nhiêu lần. Nâng cao: hãy sắp xếp các từ theo thứ tự từ điển trước khi in ra kết quả. . Chương 5: Mảng băm 1. Mảng băm 2. Biến mảng băm 3. Biểu diễn hằng ký hiệu cho mảng băm 4. Các toán tử trên mảng băm 5. Bài tập 5.1 Mảng băm Mảng băm cũng tựa. mảng băm con vào một mảng băm khác lớn hơn. Hãy xem ví dụ sau, mảng băm con được ưu tiên hơn: nếu có cùng một khoá tồn tại trong cả mảng băm con và mảng băm

Ngày đăng: 04/11/2013, 11:15

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan