Nối hai chuỗi nhưng cho phép một mức độ lỗi


10

Làm cách nào tôi có thể khớp hai chuỗi, nhưng đồng thời cho phép số lượng ký tự X không chính xác trong trận đấu. Số lượng lỗi phải là một biến có thể kiểm soát.

Mặc dù số lượng ký tự X không thể khớp trong chuỗi, nên có giới hạn về số lượng chạy trong một chuỗi. Cho hai chuỗi tôi có thể cho phép 5 ký tự khác nhau, nhưng không quá 2 chuỗi liên tiếp.

Tôi đang tìm kiếm một thuật toán được đề xuất để so sánh hai chuỗi này hoặc có thể đã có một giải pháp đã biết cho việc này.


4
Các khoảng cách Levenshtein có thể là một cái gì đó để xem xét, mặc dù các chi tiết cụ thể của 'không quá 2 liên tiếp' không phải là một phần của thuật toán đó. Trang xem thêm có rất nhiều thuật toán liên quan khác có thể là những gì bạn đang tìm kiếm.

@MichaelT nếu tôi có một cái gì đó như thế chắc chắn sẽ phù hợp với nhu cầu của tôi. cảm ơn.
Phản ứng

@MichaelT Tôi tìm thấy cái này> dotnetperls.com/levenshtein Bạn nên đặt nó làm câu trả lời vì điều này đã giải quyết vấn đề của tôi.
Phản ứng

Bạn có thể muốn xem kết hợp Soundex. vi.wikipedia.org/wiki/Soundex
Gilbert Le Blanc

Câu trả lời:


12

Điểm bắt đầu tìm kiếm chuỗi gần đúng là khoảng cách Levenshtein . Thuật toán này đếm số lần chỉnh sửa ký tự đơn (chèn, xóa và thay thế) để thay đổi một từ thành một từ khác.

Một ví dụ về điều này là kitten-> sittingcó khoảng cách chỉnh sửa là ba

  1. k itten -> s itten (thay thế 's' cho 'k')
  2. sitt e n -> sitt i n (thay thế 'i' cho 'e')
  3. sittin -> sittin g (thêm 'g' ở cuối)

Có các biến thể của thuật toán này, đáng chú ý là khoảng cách Damensau của Levenshtein cho phép hoán vị hai ký tự liền kề ('hte' thành 'the' có khoảng cách DL là 1 và khoảng cách Levenshtein là 2) và do đó thường thích hợp hơn cho kiểm tra chính tả. Các biến thể khác tồn tại cho các ứng dụng trong đó khoảng trống là quan trọng (chuỗi DNA).

Khoảng cách Levenshtein rất nổi tiếng và không quá khó để tìm thấy (tôi đã từng tìm cách thực hiện nó như một chức năng trong orory - nó nhanh hơn nhiều so với việc kéo xuống tất cả dữ liệu và sau đó chạy bên mã truy vấn). Rosettacode có vô số (54) ý nghĩa về khoảng cách Levenshtein (lưu ý rằng một số ngôn ngữ có phần này như một phần của thư viện chuỗi ở đâu đó - nếu bạn đang làm Java, hãy nhìn vào apache commons lang ). Wikibooks có 31 triển khai và một cái nhìn lướt qua hai cái không hiển thị cùng một mã cho cùng một ngôn ngữ.

Cách thức hoạt động này là nó xây dựng một ma trận tương ứng với mối quan hệ giữa hai chuỗi:

 .kitten
.0123456
s1123456
i2212345
t3321234
t4432123
i5543223
n6654332
g7765443

Các .hàng và cột đại diện cho rằng bạn có thể nhận được vào chuỗi mục tiêu của 'chỉ' chèn mỗi lá thư từ một chuỗi rỗng. Đây không phải là trường hợp lý tưởng, nhưng nó ở đó để gieo mầm thuật toán.

Nếu giá trị giống với điểm đó ('i' == 'i'), giá trị này giống với giá trị theo đường chéo ở bên trái. Nếu hai điểm không giống nhau ('s'! = 'K'), giá trị là mức tối thiểu của:

  • đường chéo lên và sang trái + 1 (thay thế)
  • trực tiếp trên + 1 (một chèn)
  • trực tiếp bên trái + 1 (xóa)

Giá trị trả về khoảng cách chỉnh sửa là giá trị ở phía dưới bên phải của ma trận.

Nếu bạn theo dõi từ phía dưới bên phải sang phía trên bên trái với mức tối thiểu, bạn có thể thấy các chỉnh sửa được thực hiện:

 .kitten
.0.   .
s.1   .
i  1  .
t   1 .
t    1.
i.....2
n      2
g......3

Hãy lưu ý rằng đây là cách tiếp cận khá bộ nhớ. Nó có thể được giảm phạm vi bộ nhớ bằng cách không xây dựng ma trận đầy đủ - tất cả các thuật toán quan tâm là một tập hợp con của dữ liệu và nó có thể được giảm từ N*Mkhông gian sang 2*max(N,M)không gian bằng cách chỉ lưu trữ hàng trước đó (và những gì đã được tính toán trên hiện tại hàng). Code Project cho thấy làm thế nào điều này có thể được thực hiện (với mã C # để tải xuống).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.