tài liệu: môi trường và công cụ lập trình pot

24 295 0
tài liệu: môi trường và công cụ lập trình pot

Đ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

Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] Chương 1: Ôn tập lớp sở 1.0 Tổng quan Trong chương ta có nhìn rõ lớp sở ( base classes) cách mà chúng tương tác với ngôn ngữ C# để hổ trợ cho ta việc viết mã.Cụ thể ta xem xét chủ đề sau : • • Chuỗi biểu thức quy ( regular expression) Nhóm đối tượng ,bao gồm danh sách mảng,collections từ điển Ta xem xét System.Object, lớp mà thứ dẫn xuất từ 1.1 System.object System.object lớp sở chung mà đối tượng khác thừa kế ta xem xét phương thức thành viên nó.Trong chương ta tìm hiểu phương thức lại system.object ta tìm hiểu tóm tắt phương thức : Phương thức Truy xuất string ToString() public virtual Trả chuỗi đại diện cho đối tượng trả mã băm đối tượng thiết kế public virtual cho phép ta tìm kiếm cách hiệu thể đối tượng từ điền so sánh đối tượng với đối tượng public virtual khác int GetHashCode() bool Equals(object obj) bool Equals(object objA, object objB) public static bool ReferenceEquals(object public static objA, object objB) Type GetType() public object MemberwiseClone() protected void Finalize() protected virtual Nguyễn Minh Hiệp  Mục đích so sánh đối tượng so sánh tham chiếu đối tượng để xem chúng có đến đối tượng trả đối tượng dẫn xuất từ System.Type mà đưa chi tiết kiểu liệu Makes a shallow copy of the object (in other words, copies data in the object but not other objects any fields refer to) Hàm hủy ( Destructor) Page 1  Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] 1.2 Xử lý chuỗi (System.string) Phương thức Mục đích Compare so sánh nội dung chuỗi CompareOrdinal giống compare khơng kể đến ngơn ngữ địa văn hố định dạng chuỗi chứa giá trị khác định cách giá trị nên định dạng Format vị trí xuất chuỗi kí tự chuỗi IndexOfAny vị trí xuất tập kí tự chuỗi LastIndexOf giống indexof , tìm lần xuất cuối LastIndexOfAny giống indexofAny , tìm lần xuất cuối canh phải chuỗi điền chuỗi cách thêm kí tự định lặp lại PadLeft vào đầu chuỗi canh trái chuỗi điền chuỗi cách thêm kí tự định lặp lại PadRigth vào cuối chuỗi Replace thay kí tự hay chuỗi chuỗi với kí tự chuỗi khác chia chuỗi thành mảng chuỗi ,ngắt xuất kí tự Split Substring trả chuỗi bắt đầu vị trí định chuỗi ToLower chuyển chuỗi thành chữ thuờng ToUpper chuyển chuỗi thành chữ in Trim bỏ khoảng trắng đầu cuối chuỗi IndexOf 1.2.1 Định dạng Chuỗi Nếu ta muốn lớp mà ta viết thân thiện với người sử dụng , chúng cần để trình bày chuỗi theo cách mà người sử dụng muốn dùng.Thời gian chạy NET định nghĩa cách chuẩn để làm : dùng interface IFormatable Ví dụ: double d = 13.45; int i = 45; Console.WriteLine("The double is {0,10:E} and the int contains {1}", d, i); Chuỗi định dạng tự bao gồm hầu hết văn trình bày,nhưng đâu có biến định dạng , mục danh sách thơng số dấu ngoặc.có thể thông tin khác bên dấu ngoặc việc định dạng mục Nguyễn Minh Hiệp  Page 2  Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] số kí tự giữ trình bày mục xuất hiện, thơng tin có dấu phảy đứng trước.một số âm định mục đưọc canh trái,trong số dương định mục canh phải mục giữ nhiều kí tự yêu cầu, xuất đầy đủ Một định định dạng xuất hiện.điều đặt trước dấu hai chấm định cách ta muốn mục định dạng ví dụ ta muốn định dạng số kiểu tiền tệ trình bày theo ký hiệu khoa học ? Đặc tả C D E F G N P X Áp dụng đến numeric types Ý nghĩa locale-specific monetary value integer types only general integer numeric types scientific notation numeric types fixed point decimal numeric types general number numeric types usual locale specific format for numbers numeric types Percentage notation integer types only hexadecimal format Ví dụ $4834.50 (USA)£4834.50 (UK) 4834 4.834E+003 4384.50 4384.5 4,384.50 (UK/USA)4 384,50 (continental Europe) 432,000.00% 1120 (NB If you want to display 0x1120, you'd need to write out the 0x separately) 1.3 Biểu thức quy ( Regular Expression) 1.3.1 Giới thiệu: Ngôn ngữ biểu thức quy ngơn ngữ thiết kế đặc biệt cho việc xử lí chuỗi.chứa đựng đặc tính : - tập mã escape cho việc xác định kiểu kí tự ta quen với việc dùng kí tự * để trình bày chuỗi biểu thức DOS biểu thức quy dùng nhiều chuỗi để trình bày mục 'bất kì kí tự' ,'1 từ ngắt ','1 kí tự tuỳ chọn', - hệ thống cho việc nhóm phần chuỗi con, trả kết suốt thao tác tìm dùng biểu thức quy , biểu diễn thao tác cấp cao phức tạp chuỗi.ví dụ : - Xác định tất từ lặp lại chuỗi , chuyển ' "The computer books books" thành "The computer books" Nguyễn Minh Hiệp  Page 3  Khoa CNTT [MÔI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] - Chuyển tất từ theo title case, chuyển "this is a Title" thàh "This Is A Title" - Chuyển từ dài kí tự thành title case , ví dụ chuyển "this is a Title" to "This is a Title" - Bảo đảm câu viết hoa - Phân cách phần tử URL sử dụng phương thức System.String System.Text.StringBuilder để làm việc dùng biểu thức quy mã giảm xuống cịn vài dòng.ta khởi tạo đối tượng System.Text.RegularExpressions.RegEx , truyền vào chuỗi xử lí, biểu thức quy ( chuỗi chứa đựng lệnh ngôn ngữ biểu thức quy ) chuỗi biểu thức quy nhìn giống chuỗi bình thường có thêm số chuỗi kí tự khác làm cho có ý nghĩa đặc biệt hơn.ví dụ chuỗi \b định việc bắt đầu hay kết thúc từ , ta muốn định tìm kí tự th bắt đầu từ, ta tìm theo biểu thức quy ,\bth muốn tìm tất xuất th cuối từ ta viết th\b nhiên , biểu thức quy phức tạp thế, ví dụ điều kiện để lưu trữ phần kí tự mà tìm thấy thao tác tìm kiếm ví dụ khác giả sử ta muốn chuyển số diện thoại UK từ nước sang định dạng quốc tế UK, định dạng ví dụ 01233 345532 (01233 345532) mà theo quốc tế +44 12330345532, nói cách khác số đầu thay +44 dấu ngặc phải bỏ Thao tác không phức tạp, rắc rối ta dùng lớp chuỗi để làm ( nghĩa dùng phương thức lớp chuỗi) ngơn ngữ biểu thức quy cho phép ta xây dựng chuỗi ngắn mà phiên dịch để đạt yêu cầu Ta xem đoạn văn chuỗi input.giả sử ta muốn tìm tất lần xuất ion ta viết sau: string Pattern = "ion"; MatchCollection Matches = Regex.Matches(Text, Pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); foreach (Match NextMatch in Matches) { Console.WriteLine(NextMatch.Index); } Trong ví dụ ta dùng phương thức tĩnh Matches() lớp Regex namespace System.Text.RegularExpressions phương thức có thơng số text, pattern, tập cờ từ cấu trúc liệt kê RegexOptions.trong trường hợp ta định tìm kiếm khơng phân biệt chữ hoa - thường cờ ExplicitCapture, cập nhật cách mà match thu thập Nguyễn Minh Hiệp  Page 4  Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] Ta thấy hàm Matches() trả tham chiếu đến đối tượng MatchCollection match thuật ngữ kĩ thuật cho kết việc tìm thể pattern biểu thức trình bày lớp System.Text.RegularExpressions.Match.do ta trả MatchCollection chứa tất match, đưọc trình bày đối tượng Match đoạn mã trên, ta đơn giản lặp tập thu dùng thuộc tính index lớp Match, mà trả mục đoạn input nơi mà match tìm thấy.khi chạy tìm match Ý nghĩa Ví dụ Examples that this will match ^ Bắt đầu chuổi nhập ^B B, kí tự chuỗi $ Kết thúc chuỗi nhập X$ X, kí tự cuối chuỗi Bất kì kí tự ngoại trừ kí tự xuống dịng(\n) i.ation isation, ization * Kí tự trước lặp lại nhiều ra*t lần rt, rat, raat, raaat, and so on + Kí tự trước lặp lại nhiều ra+t lần rat, raat, raaat and so on, (but not rt) ? Kí tự trước lặp lại lần ra?t rt and rat only \s Bất kì kí tự khoảng trắng \sa [space]a, \ta, \na (\t and \n có ý nghĩa giống C#) \S Bất kì kí tự khơng phải khoảng trắng \SF aF, rF, cF, but not \tf \b Từ biên ion\b any word ending in ion \B vị trí khơng phải từ biên \BX\B kí tự X từ 1.3.2 Trình bày kết Trong phần ta xét ví dụ RegularExpressionsPlayaround để ta thiết lập vài biểu thức quy trình bày kết để thấy cách mà biểu thức quy làm việc tâm điểm phương thức WriteMatches(), mà trình bày tất match từ MatchCollection theo định dạng chi tiết hơn.trong match , trình bày mục nơi mà match tìm thấy chuỗi nhập,chuỗi match bao gồm match cộng thêm 19 kí tự bao quanh chuỗi nhập - kí tự đứng trước kí tự đứng sau.( nhỏ kí tự match xuất kí tự phần đầu kết thúc đoạn nhập.) ví dụ match từ messaging mà xuất gần cuối chuỗi nhập đánh dấu trình bày "and messaging of d" ( kí tự trước sau match)nhưng match từ cuối data trình bày "g of data "( kí tự sau match).bởi cuối chuỗi.1 chuỗi dài để ta thấy rõ nơi biểu thức quy định vị match: Nguyễn Minh Hiệp  Page 5  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] static void WriteMatches(string text, MatchCollection matches) { Console.WriteLine("Original text was: \n\n" + text + "\n"); Console.WriteLine("No of matches: " + matches.Count); foreach (Match nextMatch in matches) { int Index = nextMatch.Index; string result = nextMatch.ToString(); int charsBefore = (Index < 5) ? Index : 5; int fromEnd = text.Length - Index - result.Length; int charsAfter = (fromEnd < 5) ? fromEnd : 5; int charsToDisplay = charsBefore + charsAfter + result.Length; Console.WriteLine("Index: {0}, \tString: {1}, \t{2}", Index, result, text.Substring(Index - charsBefore, charsToDisplay)); } } Phần lớn quy trình phương thức minh hoạ số kí tự đượctrình bày chuỗi dài mà trình bày khơng quan tâm đến đầu hay cuối chuỗi.lưu ý ta sử dụng thuộc tính khác đối tượng Match , Value, chứa chuỗi xác định Match.RegularExpressionsPlayaround chứa số phương thức với tên Find1, Find2 mà biểu diễn việc tìm kiếm dựa ví dụ phần ví dụ find2 tìm chuỗi chứa n vào lúc đầu từ : static void Find2() { string text = @"XML has made a major impact in almost every aspect of software development Designed as an open, extensible, self-describing language, it has become the standard for data and document delivery on the web The panoply of XML-related technologies continues to develop at breakneck speed, to enable validation, navigation, transformation, linking, querying, description, and messaging of data."; string pattern = @"\bn"; MatchCollection matches = Regex.Matches(text, pattern, RegexOptions.IgnoreCase); WriteMatches(text, matches); } Cùng với phương thức phương thức main() mà ta chỉnh sửa đề chọn phương thức Find( ): Nguyễn Minh Hiệp  Page 6  Khoa CNTT [MÔI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] static void Main() { Find1(); Console.ReadLine(); } 1.3.3 Matches, Groups, and Captures: đặc tính hay biểu thức quy ta nhóm kí tự làm việc theo cách lệnh hợp C# Pattern biểu thức quy ,ta nhóm kí tự (bao gồm metacharacters chuỗi escape) với nhau, kết xem kí tự đơn khác ta dùng ngoặc đơn thay cho ngoặc vuông Chuỗi kết gọi group Ví dụ pattern (an)+ định vị chuỗi an quatifier + áp dụng cho kí tự trước nó.nhưng ta nhóm chúng lại nên việc áp dụng cho an kí tự thống nhất.ví dụ ta dùng (an)+ chuỗi nhập "bananas came to Europe late in the annals of history", cho anan từ bananas, viết an+ có ann từ annals, chuỗi tách biệt an từ bananas biểu thức (an)+ bắt xuất an , anan,ananan, biểu thức an+ bắt xuất an,ann,annn, ta thắc mắc (an)+ cho anan từ bananas an , theo luật có trường hợp có khả ( an anan ) mặc định match chứa khả dài ví dụ khác : ta có URL có định dạng sau: ://: port tuỳ chọn.ví dụ URL http://www.wrox.com:4355 giả sử ta muốn lấy protocol, address,port từ URL ta biết có khoảng trắng khơng có ( khơng có dấu chấm) ta dùng biểu thức sau: \b(\S+)://(\S+)(?::(\S+))?\b Đây cách biểu thức làm việc phần đầu đuôi chỗi \b bảo đảm quan tâm đến phần kí tự mà từ nguyên vẹn , nhóm (\S+):// lấy nhiều kí tự mà khơng đếm khoảng trắng, mà theo sau :// điều lấy http:// vào phần đầu HTTP URL chuỗi (\S+)sẽ lấy phần www.wrox.com URL trên.nhóm kết thúc gặp phần cuối từ ( \b) gặp dấu hai chấm (:) đánh dấu phần Phần lấy port dấu ? định nhóm tuỳ chọn match Quan trọng số port đặc tả URL - có lúc khơng có mặt.ta muốn định dấu hai chấm xuất không, ta không muốn lưu trữ dấu hai chấm nhóm ta làm điều cách tạo group lồng bên ( \S+) lấy thứ sau dấu hai chấm ( ví dụ 4355) nhóm ngồi chứa đựng Nguyễn Minh Hiệp  Page 7  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] nhóm đứng trước dấu hai chấm mà đứng trước chuỗi ?: , chuỗi định nhóm câu hỏi khơng lưu ( ta muốn lưu 4355; không lưu :4355) đừng nhầm lẫn dấu hai chấm - dấu phần chuỗi ?: nói ' khơng lưu nhóm này' , thứ hai kí tự tìm kiếm Nếu ta chạy pattern chuỗi : Hey I've just found this amazing URI at http:// what was it - oh yes http://www.wrox.com Ta lấy match http://www.wrox.com match có nhóm đưọc đề cập nhóm khơng lấy gì, nhiều nhóm match riêng biết đến capture.vì thế, nhóm , (\s+) ,có capture , http nhóm thứ hai có capture , www.wrox.com nhóm thứ ba khơng có capture, khơng có số port URL Lưu ý chuỗi chứa nửa http:// điều không phù hợp với nhóm ta khơng lấy qua tìm kiếm biểu thức tìm kiếm đầy đủ khơng phủ hợp vời phần kí tự Ta khơng phải biểu diễn ví dụ C# mà dùng Groups captures ta đề cập lớp NET RegularExpressions hổ trợ groups captures, lớp Group Capture có lớp GroupCollection CaptureCollection ,mà trình bày việc thu thập groups captures lớp Match phơi bày phương thức ,Group() mà trả đối tượng GroupCollection lớp Group thi hành phương thức ,Captures() mà trả CaptureCollection mối quan hệ đối tượng thể qua biểu đồ sau : việc trả đối tượng Group lần ta muốn nhóm số kí tự với khơng phải ta muốn làm.có số overhead liên quan đến việc khởi tạo đối tượng, mà bị lãng phí tất ta muốn nhóm vài kí tự Nguyễn Minh Hiệp  Page 8  Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] phần pattern ta khơng cho phép điều việc bắt đầu nhóm với chuỗi kí tự ?: cho nhóm riêng ,khi ta làm ví dụ URL , cho tất nhóm việc định cờ RegExOptions.ExplicitCaptures phương thức REgEX.Matches() ta làm ví dụ trước 1.4 Nhóm đối tượng Chúng ta khảo sát số lớp sở NET có cấu trúc liệu số đối tượng nhóm với nhau.cấu trúc đơn giản mà ta học mảng, thể lớp System.Array mảng có lợi điểm ta truy nhập phần tử thông qua mục.tuy nhiên khuyết điểm ta phải khởi tạo kích thước thêm ,chèn bỏ phần tử sau đó.và phải có mục số để truy nhập vào phần tử.điều khơng tiện ví dụ ta làm việc với ghi nhân viên muốn tìm ghi theo tên nhân viên .NET có số cấu trúc liệu khác hổ trợ cho cơng việc này.ngồi cịn có số inteface , mà lớp khai báo chúng hổ trợ tất chức kiểu cụ thể cấu trúc liệu xem xét cấu trúc sau : - Array lists - Collection - Dictionary ( hay maps) Các lớp cấu trúc liệu nằm namespace System.Collection 1.4.1 Array lists Array list giống mảng, ngoại trừ có khả phát triển.được đại diện lớp System.Collection.Arraylist lớp Arraylist có một vài điểm tương tự với lớp StringBuilder mà ta tìm hiểu trưóc đây.như StringBuilder cấp phát đủ chỗ trống vùng nhớ để lưu trữ số kí tự, cho phép ta thao tác kí tự chỗ trống , the Arraylist cấp đủ vùng nhớ để lưu trữ số tham chiếu đối tượng ta thao tác tham chiếu đối tượng này.nếu ta thử thêm đối tượng đến Arraylist dung lượng cho phép nó, tự động tăng dung lượng cách cấp phát thêm vùng nhớ lớn đủ để giữ gấp lần số phần tử dung lượng thời Ta khởi tạo danh sách cách định dung lượng ta muốn ví dụ , ta tạo danh sách Vectors: ArrayList vectors = new ArrayList(20); Nguyễn Minh Hiệp  Page 9  Khoa CNTT [MÔI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] Nếu ta khơng định kích cỡ ban đầu , mặc định 16: ArrayList vectors = new ArrayList(); // kích cỡ 16 Ta thêm phần tử cách dùng phương thức Add(): vectors.Add(new Vector(2,2,2)); vectors.Add(new Vector(3,5,6)); Arraylist xem tất phần tử tham chiếu đối tượng Nghĩa ta lưu trữ đối tượng mà ta muốn Arraylist truy nhập đến đối tượng, ta cần ép kiểu chúng trở lại kiểu liệu tương đương: Vector element1 = (Vector)vectors[1]; Ví dụ Arraylist định nghĩa indexer, để ta truy nhập phần tử với cấu trúc mảng ta chèn phần tử vào array list: vectors.Insert(1, new Vector(3,2,2)); // chèn vào vị trí Đây phương thức nạp chồng có ích ta muốn chèn tất phần tử collection vào arraylist ta bỏ phần tử : vectors.RemoveAt(1); // bỏ đối tượng vị trí Ta cung cấp đối tượng tham chiếu đến phương thức khác, Remove().nhưng làm điều nhiều thời gian arraylist phải quét qua tồn mảng để tìm đối tượng Lưu ý việc thêm bỏ phần tử làm cho tất phần tử theo sau phải bị thay đổi tương ứng nhớ, chí cần tái định vị tồn Arraylist Ta cập nhật đọc dung lượng qua thuộc tính : vectors.Capacity = 30; Tuy nhiên việc thay đổi dung lương làm cho tồn Arraylist tái định vị đến khối nhớ với dung lượng đưọc yêu cầu Để biết số phần tử thực arraylist ta dùng thuộc tính Count : int nVectors = vectors.Count; Nguyễn Minh Hiệp  Page 10  Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] arraylist thực hữu ích ta cần xây dựng mảng đối tuợng mà ta khơng biết kích cỡ mảng trường hợp đó, ta xây dựng ' mảng' Arraylist, sau chép Arraylist trở lại mảng ta hồn thành xong ta thực cần liệu mảng ( ví dụ mảng truyền đến phương thức xem mảng thông số) mối quan hệ Arraylist Array theo cách giống mối quan hệ StringBUilder String khơng lớp StringBuilder, khơng có phương thức đơn để làm việc chuyển đổi từ arraylist sang array ta phải dùng vòng lặp để chép thủ công trở lại.tuy nhiên ta phải chép tham chiếu đối tượng: // vectors is an ArrayList instance being used to store Vector instances Vector [] vectorsArray = new Vector[vectors.Count]; for (int i=0 ; i< vectors.Count ; i++) vectorsArray[i] = (Vector)vectors [i]; 1.4.2 Collections Ý tưởng Collection trình bày tập đối tượng mà ta truy xuất việc bước qua phần tử cụ thể tập đối tượng mà ta truy nhập sử dụng vịng lặp foreach nói cách khác ,khi viết thứ : foreach (string nextMessage in messageSet) { DoSomething(nextMessage); } Ta xem biến messageSet collection khả để dùng vịng lặp foreach mục đích collection ta tìm hiểu chi tiết collection thi hành collection riêng việc chuyển ví dụ Vector mà ta phát triển 1.4.2.1 Collection ? đối tượng collection cung cấp tham chiếu đến đối tượng có liên quan, biết đến enumarator, mà duyệt qua mục collection đặc biệt hơn, collection phải thi hành interface System.Collections.IEnumerable IEnumerable định nghĩa phương thức sau: interface IEnumerable { Nguyễn Minh Hiệp  Page 11  Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] IEnumerator GetEnumerator(); } Mục đích GetEnumarator() để trả đối tuợng enumarator ta tập họp đoạn mã đối tượng enumarator mong đợi để thi hành interface , System.Collections.IEnumerator Ngồi cịn có interface khác , Icollection , đưọc dẫn xuất từ IEnumerable collection phức tạp thi hành interface này.bên cạnh GetEnumerator(), thi hành thuộc tính trả trực tiếp số phần tử collection có đặc tính hổ trợ việc chép collection đến mảng cung cấp thơng tin đặc tả luồng an tồn.tuy nhiên phần ta xem xét interface IEnumerable IEnumarator có cấu trúc sau: interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); } IEnumarator làm việc sau : đối tuợng thực thi nên kết hợp với collection cụ thể đối tượng khởi động lần đầu tiên,nó chưa trỏ đến phần tử collection, ta phải gọi MoveNext(), mà di chuyển enumarator để chuyển đến phần tử collection ta nhận phần tử với thuộc tính Current.Current trả tham chiếu đối tượng , ta ép kiểu kiểu đối tượng mà ta muốn tìm Collection.ta làm điều ta muốn với đối tượng sau di chuyển đến mục collection cách gọi MoveNext() lần nữa.ta lập lại hết mục collection- current trả null.nếu muốn ta quay trở vị trí đầu collection cách gọi Reset() lưu ý Reset() thực trả trước bắt đầu collection , muốn di chuyển đến phần tử ta phải gọi MoveNext() m collection kiểu nhóm đối tượng.bởi khơng cho phép ta thêm bỏ mục nhóm.tất ta làm nhận mục theo thứ tự định collection.và kiểm tra chúng.thậm chí ta khơng thể thay cập nhật mục thuộc tính current đọc.hầu cách dùng thường collection cho ta thuận tiện cú pháp lặp foreach Mảng collection, lệnh foreach làm việc tốt mảng Ta xem vịng lặp foreach C# cú pháp ngắn việc viết: { IEnumerator enumerator = MessageSet.GetEnumerator(); string nextMessage; Nguyễn Minh Hiệp  Page 12  Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] enumerator.MoveNext(); while ( (nextMessage = enumerator.Current) != null) { DoSomething(nextMessage); // NB We only have read access // toNextMessage enumerator.MoveNext(); } } khía cạnh quan trọng collection đếm trả đối tượng riêng biệt.lý phép khả có nhiều đếm áp dụng đồng thời collection 1.4.2.2 Thêm collection hổ trợ cấu trúc Vector Trong lần cuối ta nói Vector , thể Vector chứa đựng phần, x,y,z ta định nghĩa mục chương 3, đuợc xem thể Vector mảng , để ta truy nhập vào phần x cách viết someVector[0], phần y cách viết someVecor[1] z someVector[2] Bây ta mở rộng cấu trúc vector, dự án VectorAsCollection mà quét qua phần vector cách viết : foreach (double component in someVector) Console.WriteLine("Component is " + component); Nhiệm vụ ta biểu thị vector collection việc cho thực thi interface IEnumerable, ta bắt đầu việc cập nhật khai báo cấu trúc vector: struct Vector : IFormattable, IEnumerable { public double x, y, z; Bây ta thi hành interface IEnumerable : public IEnumerator GetEnumerator() { return new VectorEnumerator(this); } Việc thi hành GetEnumerator() đơn giản, tuỳ thuộc tồn lớp mới, VectorEnumerator,mà ta cần định nghĩa VectorEnumerator khơng phải lớp mà đoạn mã bên ngồi thấy trực tiếp, ta khai báo lớp private bên cấu trúc Vector việc định nghĩa sau: Nguyễn Minh Hiệp  Page 13  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] private class VectorEnumerator : IEnumerator { Vector theVector; // Vector object that this enumerato refers to int location; // which element of theVector the enumerator is // currently referring to public VectorEnumerator(Vector theVector) { this.theVector = theVector; location = -1; } public bool MoveNext() { ++location; return (location > 2) ? false : true; } public object Current { get { if (location < || location > 2) throw new InvalidOperationException( "The enumerator is either before the first element or " + "after the last element of the Vector"); return theVector[(uint)location]; } } public void Reset() { location = -1; } } Khi yêu cầu đếm, VectorEnumerator thi hành interface IEnumerator chứa trường thành viên, theVector,1 tham chiếu đến Vector ( collection) mà đếm kết hợp, location, số nguyên mà định nơi collection mà đếm tham chiếu đến Cách làm việc xem location mục thi hành enumerator để truy nhập Vector mảng.khi truy nhập vector mảng giá trị mục 0,1,2 - tamở rộng cách dùng -1 giá trị định đếm trước bắt đầu collection,và để Nguyễn Minh Hiệp  Page 14  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] đến cuối collection , việc khởi tạo trường -1 hàm dựng VectorEnumerator : public VectorEnumerator(Vector theVector) { this.theVector = theVector; location = -1; } Lưu ý hàm dựng lấy tham chiếu đến thể Vector mà định đếm - điều cung cấp phương thức Vector.GetEnumerator : public IEnumerator GetEnumerator() { return new VectorEnumerator(this); } 1.4.3 Dictionaries Từ điển trình bày cấu trúc liệu phức tạp mà cho phép ta truy nhập vào phần tử dựa khoá đó, mà kiểu liệu bất kì.ta hay gọi bảng ánh xạ hay bảng băm.Từ điển dùng ta muốn lưu trữ liệu mảng muốn dùng kiểu liệu thay cho kiểu liệu số làm mục.nó cho phép ta thêm bỏ mục , giống danh sách mảng nhiên khơng phải dịch chuyển mục phía sau nhớ Ta minh họa việc dùng từ điển ví dụ sau :MortimerPhonesEmployees Trong ví dụ cơng ty điện thoại có vài phần mềm xử lí chi tiết nhân viên Ta cần cấu trúc liệu -hơi giống mảng- mà chứa liệu nhân viên.ta giả sử nhân viên công ty xác định ID nhân viên,là tập kí tự B342 lưu trữ thành đối tượng EmployyeeID.chi tiết nhân viên lưu trữ thành đối tượng EmployeeData, ví dụ chứa ID ,tên, lương nhân viên giả sử ta có EmployeeID: EmployeeID id = new EmployeeID("W435"); ta có biến gọi employees, mà ta xem mảng đối tượng Nguyễn Minh Hiệp  Page 15  Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] EmployeeData.thực , khơng phải mảng - từ điển từ điển nên ta lấy chi tiết nhân viên thơng qua ID đuợc khai báo trên: EmployeeData theEmployee = employees[id]; // lưu ý ID khơng phải kiểu số- thể EmployeeID Đó sức mạnh từ điển.Ta dùng kiểu liệu làm mục , lúc ta gọi khố khơng phải mục nữa.khi ta cung cấp khoá truy nhập vào phần tử ( ID ), xử lí giá trị khoá trả số nguyên tuỳ thuộc vào khoá, dùng để truy nhập vào 'mảng' để lấy liệu 1.4.3.1 Từ điển NET Trong NET , từ điển trình bày qua lớp Hasthable, mà cách làm việc giống từ điển thực, ngoại trừ xem khố mục có kiểu object.nghĩa bảng băm lưu trữ cấu trúc liệu ta muốn ta tự định nghĩa lớp từ điển riêng cụ thể hơn.Microsoft cung cấp lớp sở trừu tượng,DictionaryBase,cung cấp chức từ điển ,mà ta dẫn xuất đến lớp mà ta muốn tạo.nếu khố chuỗi ta dùng lớp System.Collections.Specialized.StringDictionary thay cho Hasthable tạo Hasthable ta định kích thước khởi tạo nó: Hasthable employees = new Hasthable(53); Ở ta chọn số 53 thuật tốn bên dùng cho từ điển làm việc hiệu kích thước số nguyên tố Thêm đối tượng vào từ điển ta dùng phương thức Add(), có thông số kiểu object : thông số đầu khoá, thứ hai tham chiếu đến liệu ví dụ: EmployeeID id; EmployeeData data; // khởi tạo id liệu // giả sử employees thể bảng băm //mà chứa đựng tham chiếu EmployeeData employees.Add(id, data); để nhận liệu ta cung cấp khố cho nó: EmployeeData data = employees[id]; để bỏ mục ta cung cấp khoá gọi : Nguyễn Minh Hiệp  Page 16  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] employees.Remove(id); Để đếm số mục từ điển ta dùng thuộc tính Count: int nEmployees = employees.Count; Việc lưu trữ từ điển không theo phải theo kiểu từ xuống, nghĩa ta khơng thể tìm thấy khối lớn liệu phần đầu cấu trúc khối rỗng phần cuối biểu đồ sau minh hoạ cho việc lưu trữ từ điển, phần không đánh dấu rỗng: 1.4.3.2 Cách từ điển làm việc: Hasthable ( hay lớp từ điển khác) sử dụng vài thuật toán để thực việc đặt đối tượng dựa khố có giai đoạn, phần mã cho giai đoạn phải cung cấp lớp khoá.nếu sử dụng lớp Microsoft viết, mà dùng làm khố ( chuỗi), khơng có vấn đề ( Microsoft viết sẵn rồi) lớp khố ta viết ta phải tự viết phần thuật toán phần thuật toán thực thi lớp khoá gọi băm ( có thuật ngữ bảng băm)và lớp Hasthable tìm nơi cụ thể cho thuật tốn băm nhìn vào phương thức Gethashcode() đối tượng ta, mà thừa kế từ System.Object() ta nạp chồng GetHashCode() Cách làm việc Gethashcode() trả vế số ngun.bằng cách dùng giá trị khố để sinh số nguyên.Hasthable lấy số nguyên làm việc xử lí khác mà liên quan đến việc tính tốn tốn học phức tạp,và trả mục mục đưọc lưu trữ tương ứng với khóa từ điển.ta khơng sâu vào thuật tốn ta tìm hiểu liên quan đến số nguyên tố dung lượng bảng băm nên số nguyên tố Nguyễn Minh Hiệp  Page 17  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] Có số u cầu nghiêm ngặt ta nạp chồng GetHashCode() yêu cầu nghe trừu tượng qua ví dụ MortimerPhonesEmployees ta thấy khơng q khó để viết lớp khố thỏa mãn địi hỏi sau: - Nó phải nhanh ( việc đặt lấy mục từ điển coi nhanh) - Nó phải đồng - ta cho khoá giá trị chúng phải cho giá trị băm - Cho giá trị khoảng giá trị số kiểu int ( it should ideally give values that are likely to be evenly distributed across the entire range of numbers that an int can store ) Lí điều kiện cuối : điều xảy ta lấy mục từ điển mà băm hai cho mục? Nếu điều xảy ra, lớp từ điển phải bắt đầu tìm kiếm vị trí trống có giá trị gần để lưu trữ mục thứ hai Xung đột khóa gia tăng từ điển đầy,vì cách tốt bảo đảm dung lượng lớn số phần tử thực nó.vì lí mà Hasthable tự định vị lại kích cỡ để tăng dung lượng trước đầy.tỷ lệ bảng mà đầy gọi load ta thiết lập giá trị lớn mà ta muốn load đến trước Hasthable tái định vị theo hàm dựng Hasthable khác : // dung lượng =50, Max Load = 0.5 Hasthable employees = new Hasthable(50, 0.5); Max load nhỏ bảng băm làm việc hiệu cần nhiều vùng nhớ.khi bảng băm tái định vị để tăng dung lượng , ln chọn số nguyên tố làm dung lượng Một điểm quan trọng khác thuật toán băm phải đồng nhất.nếu đối tượng chứa ta coi liệu trùng, chúng phải cho giá trị băm, điều dẫn đến giới hạn quan trọng cách nạp chồng phương thức Equals() Gethashcode() System.Object cách mà Hasthable định khố a b gọi a.equals(b) nghĩa ta phải điều sau : Nếu a.equals(b) a.gethashcode() b.gethashcode() phải trả mã băm Nếu ta cố ý nạp chồng phương thức để câu lệnh khơng bảng băm khơng làm việc bình thường ví dụ ta đặt đối tượng vào bảng băm khơng nhận lại hay nhận lại không mục system.object điều kiện , Equals() đơn giản so sánh tham chiếu Nguyễn Minh Hiệp  Page 18  Khoa CNTT [MƠI TRƯỜNG VÀ CƠNG CỤ LẬP TRÌNH] gethashcode() thực trả băm dựa địa đối tượng.nghĩa bảng băm dựa khoá mà không nạp chồng phương thức làm việc đúng.tuy nhiên ,vấn đề với cách làm khóa coi chúng đối tượng.nghĩa đặt đối tượng vào từ điển ta phải nối tham chiếu đến khóa.ta khơng thể khởi tạo khóa khác sau mà có giá trị,vì giá trị định nghĩa theo nghĩa thực thể nghĩa ta không nạp chồng object Equals() Gethashcode(), lớp ta không thuận lợi để dùng bảng băm tốt thi hành gethashcode() sinh băm dựa giá trị khoá điạ nhớ.do ta cần nạp chồng gethashcode() va equals() lớp mà ta muốn sử dụng khố System.String có phương thức nạp chồng tương đương, Equals() nạp chồng để cung cấp giá trị so sánh, gethashcode() nạp chồng để trả băm dựa giá trị chuỗi.vì lí thuận lợi để dùng chuỗi khố từ điển 1.4.3.3 Ví dụ MortimerPhonesEmployees Đây chương trình thiết lập từ điển nhân viên.chương trình khởi tạo từ điển , thêm vài nhân viên sau mời người dùng gõ vào Id nhân viên gõ , chương trình dùng ID để trỏ vào tử điển nhận chi tiết nhân ivên quy trình lặp lại người dùng gõ X : MortimerPhonesEmployees Enter employee ID (format:A999, X to exit)> B001 Employee: B001: Mortimer £100,000.00 Enter employee ID (format:A999, X to exit)> W234 Employee: W234: Arabel Jones £10,000.00 Enter employee ID (format:A999, X to exit)> X Các lớp chương trình : class EmployeeID { private readonly char prefix; private readonly int number; public EmployeeID(string id) { prefix = (id.ToUpper())[0]; number = int.Parse(id.Substring(1,3)); } public override string ToString() { Nguyễn Minh Hiệp  Page 19  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] return prefix.ToString() + string.Format("{0,3:000}", number); } public override int GetHashCode() { return ToString().GetHashCode(); } public override bool Equals(object obj) { EmployeeID rhs = obj as EmployeeID; if (rhs == null) return false; if (prefix == rhs.prefix && number == rhs.number) return true; return false; } } Phần định nghĩa lớp lưu trữ ID.bao gồm kí tự chữ đứng đầu theo sau kí tự số ta dùng kiểu char để lưu chữ đầu int để lưu phần sau Hàm dựng nhận chuỗi ngắt thành trường này.phuơng thức Tostring() trả ID chuỗi: return prefix.ToString() + string.Format("{0,3:000}", number); Phần đặc tả định dạng (0,3:000) để phần int chứa số điền thêm số ví dụ ta có B001 khơng phải B1ta đến phương thức nạp chồng từ điển : Đầu tiên Equals() để so sánh giá trị thể EmployeeID : public override bool Equals(object obj) { EmployeeID rhs = obj as EmployeeID; if (rhs == null) return false; if (prefix == rhs.prefix && number == rhs.number) return true; return false; } } Đầu tiên ta kiểm tra xem đối tượng thơng số có phải thể EmployeeID khơng cách thử ép kiểu thành đối tượng EmployeeID sau ta việc so sánh Nguyễn Minh Hiệp  Page 20  ... giá trị định đếm trước bắt đầu collection ,và để Nguyễn Minh Hiệp  Page 14  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] đến cuối collection , việc khởi tạo trường -1 hàm dựng VectorEnumerator : public... dấu hai chấm ( ví dụ 4355) nhóm ngồi chứa đựng Nguyễn Minh Hiệp  Page 7  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] nhóm đứng trước dấu hai chấm mà đứng trước chuỗi ?: , chuỗi định nhóm câu hỏi... private bên cấu trúc Vector việc định nghĩa sau: Nguyễn Minh Hiệp  Page 13  Khoa CNTT [MÔI TRƯỜNG VÀ CÔNG CỤ LẬP TRÌNH] private class VectorEnumerator : IEnumerator { Vector theVector; // Vector object

Ngày đăng: 12/07/2014, 22:20

Từ khóa liên quan

Mục lục

  • Chương 1: Ôn tập các lớp cơ sở

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

Tài liệu liên quan