Khoảng cách chỉnh sửa (hoặc Levenshtein) giữa hai chuỗi là số lần chèn, xóa và thay thế ký tự đơn tối thiểu cần thiết để chuyển đổi một chuỗi thành chuỗi khác. Nếu hai chuỗi có độ dài n mỗi chuỗi, thì điều này có thể được thực hiện trong thời gian O (n ^ 2) bằng lập trình động. Mã Python sau đây thực hiện phép tính này cho hai chuỗi s1
và s2
.
def edit_distance(s1, s2):
l1 = len(s1)
l2 = len(s2)
matrix = [range(l1 + 1)] * (l2 + 1)
for zz in range(l2 + 1):
matrix[zz] = range(zz,zz + l1 + 1)
for zz in range(0,l2):
for sz in range(0,l1):
if s1[sz] == s2[zz]:
matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz])
else:
matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz] + 1)
return matrix[l2][l1]
Trong tác vụ này, bạn phải tiến gần đến mức có thể tính toán khoảng cách chỉnh sửa nhưng với sự hạn chế bộ nhớ nghiêm trọng. Mã của bạn được phép xác định một mảng chứa 1000 số nguyên 32 bit và đây là lưu trữ tạm thời duy nhất bạn sử dụng trong tính toán của mình. Tất cả các biến và cấu trúc dữ liệu sẽ được chứa trong mảng này. Cụ thể, bạn sẽ không thể thực hiện thuật toán ở trên như đối với các chuỗi có độ dài 1000 vì nó sẽ yêu cầu bạn lưu trữ ít nhất 1.000.000 số. Trường hợp ngôn ngữ của bạn không tự nhiên có số nguyên 32 bit (ví dụ Python), bạn chỉ cần đảm bảo rằng bạn không bao giờ lưu trữ một số lớn hơn 2 ^ 32-1 trong mảng.
Bạn có thể đọc dữ liệu bằng bất kỳ thư viện tiêu chuẩn nào bạn chọn mà không phải lo lắng về các hạn chế bộ nhớ trong phần đó. Để làm cho cạnh tranh công bằng cho phần chính của mã của bạn, bạn chỉ có thể sử dụng các hoạt động tương đương về chức năng với các hoạt động trong ngôn ngữ lập trình C và không thể sử dụng bất kỳ thư viện bên ngoài nào.
Để rõ ràng hơn, bộ nhớ để lưu trữ dữ liệu đầu vào hoặc được sử dụng bởi trình thông dịch ngôn ngữ của bạn, JVM, v.v. không được tính vào giới hạn của bạn và bạn không được ghi bất cứ điều gì vào đĩa. Bạn phải giả sử dữ liệu đầu vào là chỉ đọc khi trong bộ nhớ để bạn không thể sử dụng lại dữ liệu đó để có thêm không gian làm việc.
Tôi phải làm gì?
Mã của bạn nên đọc trong một tệp theo định dạng sau. Nó sẽ có ba dòng. Dòng đầu tiên là khoảng cách chỉnh sửa thực sự. Thứ hai là chuỗi 1 và thứ ba là chuỗi 2. Tôi sẽ kiểm tra nó với dữ liệu mẫu tại https://bpaste.net/show/6905001d52e8 trong đó các chuỗi có độ dài 10.000 nhưng không nên chuyên dụng cho dữ liệu này. Nó sẽ xuất ra khoảng cách chỉnh sửa nhỏ nhất mà nó có thể tìm thấy giữa hai chuỗi.
Bạn cũng sẽ cần phải chứng minh khoảng cách chỉnh sửa của mình thực sự đến từ một tập hợp chỉnh sửa hợp lệ. Mã của bạn nên có một công tắc biến nó thành chế độ có thể sử dụng nhiều bộ nhớ hơn (bao nhiêu tùy thích) và đưa ra các thao tác chỉnh sửa cung cấp khoảng cách chỉnh sửa của bạn.
Ghi bàn
Điểm của bạn sẽ là (optimal edit distance/divided by the edit distance you find) * 100
. Để bắt đầu mọi thứ, hãy lưu ý rằng bạn có thể nhận được điểm bằng cách chỉ đếm số lượng không khớp giữa hai chuỗi.
Bạn có thể sử dụng bất kỳ ngôn ngữ nào bạn thích có sẵn miễn phí và dễ cài đặt trong Linux.
Cà vạt
Trong trường hợp hòa vốn, tôi sẽ chạy mã của bạn trên máy Linux của tôi và mã nhanh nhất sẽ thắng.
{ uint32_t foo[1000]; for (foo[0] = 0; foo[0] < 5; ++foo[0]) printf("%d ", foo[0]); }
này Giả sử mảng số nguyên 32 bit của bạn sẽ được gọi foo
.
for(int i=0;i<=5;i++)
được phép vì nó lưu trữ dữ liệu trongi
?