Danh mục

Ứng dụng thuật toán xâu con chung dài nhất trong so sánh mã nguồn chương trình

Số trang: 5      Loại file: pdf      Dung lượng: 231.43 KB      Lượt xem: 14      Lượt tải: 0    
Thư Viện Số

Hỗ trợ phí lưu trữ khi tải xuống: miễn phí Tải xuống file đầy đủ (5 trang) 0

Báo xấu

Xem trước 2 trang đầu tiên của tài liệu này:

Thông tin tài liệu:

Trong xử lý văn bản nói chung và mã nguồn chương trình nói riêng, việc tìm ra những phần giống nhau trong các văn bản hay mã nguồn chương trình có vai trò khá quan trọng, nhất là khi cần phát hiện sự sao chép code. Trong bài viết này, chúng tôi muốn giới thiệu thuật toán và các phương pháp xử lí liên quan nhằm tìm ra những phần giống nhau trong các code với độ phức tạp về mặt thời gian và chi phí bộ nhớ là tuyến tính, độ chính xác cao kể cả trong một số trường hợp đặc biệt.
Nội dung trích xuất từ tài liệu:
Ứng dụng thuật toán xâu con chung dài nhất trong so sánh mã nguồn chương trình Trần Ngọc Hà và đtg Tạp chí KHOA HỌC & CÔNG NGHỆ 80(04): 109 - 113 ỨNG DỤNG THUẬT TOÁN XÂU CON CHUNG DÀI NHẤT TRONG SO SÁNH MÃ NGUỒN CHƯƠNG TRÌNH Trần Ngọc Hà1*, Triệu Hải Long1, Nguyễn Ngọc Tuấn2 1 2 Trường Đại học Sư phạm, Đại học Thái Nguyên, K17 Khoa học máy tính, Đại học Công Nghệ, Đại học Quốc gia Hà Nội TÓM TẮT Trong xử lý văn bản nói chung và mã nguồn chương trình nói riêng, việc tìm ra những phần giống nhau trong các văn bản hay mã nguồn chương trình có vai trò khá quan trọng, nhất là khi cần phát hiện sự sao chép code. Trong bài viết này, chúng tôi muốn giới thiệu thuật toán và các phương pháp xử lí liên quan nhằm tìm ra những phần giống nhau trong các code với độ phức tạp về mặt thời gian và chi phí bộ nhớ là tuyến tính, độ chính xác cao kể cả trong một số trường hợp đặc biệt. Từ khóa: So sánh văn bản, xâu con chung dài nhất, mã nguồn, danh sách kề, sắp xếp đếm phân phối MỞ ĐẦU* Mã nguồn là một dãy các câu lệnh được viết bằng một ngôn ngữ lập trình. Tìm phần chung giữa các code được hiểu là tìm các đoạn code có sự trùng lặp hoàn toàn hoặc một phần, có thể về nội dung hoặc cấu trúc đoạn code. Khi làm việc với code, nhất là code do người khác viết ra (cùng nhóm, học sinh...), việc tìm ra những phần giống nhau giúp giảm bớt thời gian, chi phí thực hiện, phát hiện sự sao chép... Tuy nhiên việc này gặp nhiều khó khăn như sự phức tạp của các ngôn ngữ lập trình, về mặt cú pháp, cách sử dụng câu lệnh... ví dụ ngôn ngữ lập trình Pascal không phân biệt kí tự thường và hoa, cản trở việc nhận dạng từ. Ở mức cao hơn, việc so sánh đoạn code gần giống nhau, như về câu lệnh, cấu trúc (ví dụ đoạn code chỉ khác nhau ở tên biến) hay có sự thêm bớt đoạn code khác thì chỉ cần đưa ra đoạn giống nhau. Hiện nay đã có nhiều nghiên cứu về so sánh văn bản[2][3][6][7] nhưng các phương pháp đề xuất chưa xử lí được với code. Để giải quyết các vấn đề trên chúng tôi đề xuất thuật toán xử lý được mô tả qua các bước như sau: Ta tạm coi code là chuỗi kí tự đã loại bỏ kí tự điều khiển, chú thích… chỉ bao gồm các từ khóa (ví dụ var, if, for), câu lệnh (=, >, A[j] then Begin tg:=A[j-1]; A[j-1]:=A[j]; A[j]:=tg; End; a. Code1 For x:=2 to n do For y:=n downto x1 do If A[y-1]>A[y] then Begin tg:=A[y-1]; A[y-1]:=A[y]; A[y]:=tg; End; b. Code2 For i:=2 to n do For j:=n downto i do If A[j-1]>A[j] then Begin tg:=A[j-1]; A[j-]:=A[j]; A[j]:=tg; End; c. Dãy từ chung code1 và code2 (phần chung được đánh dấu bằng phần gạch chân). 110 80(04): 109 - 113 Trong ví dụ trên cả hai đoạn mã nguồn trên chỉ khác nhau ở tên biến nhưng cấu trúc câu lệnh giống nhau, code1 sử dụng “i” và “j” còn code2 dùng “x” và “y”, tuy nhiên cùng mô tả thuật toán sắp xếp nổi bọt, ta cần nhận dạng, đánh dấu cho bước xử lý sau đó. Xử lý biến: Quá trình này tìm ra mối liên quan giữa các biến trong code1 và code2, Trong so sánh code nếu code2 sử dụng 1 phần mã code1 thì các biến trong phần code đó giống hệt nhau, ta chỉ việc đánh dấu các biến đó trong code1 và code2. Tuy nhiên nếu code2 chỉ sử dụng một phần, hay thay chỉ thay đổi tên biến khác đi so với code1, thì cần nhận dạng sự tương ứng giữa các biến dựa trên dãy từ chung tìm được trước đó. Nếu vai trò 2 biến như nhau ta coi 2 biến đó là tương đương. Trong ví dụ 1 thì “i” và “x” là tương đương, và chúng ta có thể nhận biết điều này vì liền kề với “i” trong code1 và “x” trong code2 là dãy từ chung của 2 code và từ chung này giống nhau, ngoài ra vị trí, số lượng xuất hiện cũng trùng lặp, những cơ sở đó giúp ta đưa ra kết luận tương đương các biến , còn biến “i” và “y” không tương đương vì số lượng, vị trí xuất hiện không giống nhau. Truy vết & output: các dãy từ dài nhất không lưu trực tiếp trong bộ nhớ mà lưu dưới dạng dãy chỉ số từ trong code2, từ dãy chỉ số này ta khôi phục dãy từ chung và đưa ra output. CẢI TIẾN THUẬT TOÁN TÌM DÃY CHUNG DÀI NHẤT Sau khi tách được các từ trong code1 và code2, từ 2 dãy từ (input) nhiệm vụ của chúng ta là tìm dãy chung dài nhất giữa 2 dãy, sau đó đánh dấu và đưa ra output của bài toán. Để tiện theo dõi ta coi code1 là một dãy các từ đặt trong mảng A[n] (n là số từ code1),tương tự code2 là B[m] với m là số từ trong code2. Thuật toán tìm dãy từ trên thuật toán Hunt [5] có nhiệm vụ tìm ra dãy từ chung dài nhất từ A[n] và B[m] sao cho dãy chung có các từ xuất hiện trong code1 và code2 là gần nhất. Tư tưởng chung của thuật toán như sau: A[i]=B[j]với mỗi A[i] ta định vị một từ B[j] tương ứng sao cho: Trần Ngọc Hà và đtg Tạp chí KHOA HỌC & CÔNG NGHỆ  A[i ] = B[j ]   j min Để làm việc này ta sử dụng một mảng THRESH[O:n] để lưu vị trí j min trong B sao cho A[i]=B[j] và có thể chèn vào dãy từ chung. Với mỗi A[i] nếu được định vị trong B làm tăng kích thước THRESH lên 1 đơn vị, cuối cùng kích thước THRESH chính là độ dài dãy từ lớn nhất. Tuy nhiên dãy THRESH chứa vị trí các từ trong B chưa chắc đã là vị trí các từ thuộc dãy chung lớn nhất, mà chúng được lưu lại trong danh sách LINK, gồm thông tin nối từ i sang j và từ chung trước đó LINK[k-1]. Cuối cùng sử dụng danh sách LINK để khôi phục dãy chung dài nhất. Để tăng tốc thuật toán và giảm bớt bộ nhớ, với mỗi A[i] thay vì lần lượt tìm B[j] ta tìm B[j] qua mảng MATCHLIST chứa chỉ số các từ trùng lặp B[j] được xây dựng trước đó. Ví dụ A=”a b c b d d a” B=”b a d b a b d” MATCHLIST[1] = (5, 2) MATCHLIST[2] = (6, 4, 1) MATCHLIST[3] = ( ) MATCHLIST[4] = MATCHLIST[2] MATCHLIST[5] = (7, 3) MATCHLIST[6] = MATCHLIST[5] MATCHLIST[7] = MATCHLIST[I] Hay để giảm chi phí tìm kiếm và bộ nhớ hơn nữa có thể tổ chức MATCHLIST dưới dạng danh sách kề (adjacency list)[1]. Chi tiết thuật toán như sau: integer array THRESH[O:n]; list array MATCHLIST[1 :n]; pointer array LINK[1 :n]; pointer PTR; Step 1: Xây dựng MATCHLIST; for i := 1 step 1 until n do set MATCHLIST[i] : (j1 ,j2, ... ,jp) such that j1 >j2 > ... >jp and code1[i] = code2[jq] for i ...

Tài liệu được xem nhiều: