Tìm khoảng cách chỉnh sửa tối thiểu giữa hai chuỗi


13

Giải trình

Các chỉnh sửa khoảng cách giữa hai chuỗi là một chức năng của số lượng tối thiểu có thể có của chèn, xóa, hoặc thay thế để chuyển đổi một từ vào một từ khác.

Chèn và xóa chi phí 1, và thay thế chi phí 2.

Ví dụ: khoảng cách giữa ABAlà 1, vì xóa chi phí 1 và chỉnh sửa duy nhất cần thiết là xóa Bký tự.

Khoảng cách giữa CARFARlà 2, vì chi phí thay thế 2. Một cách khác để xem xét điều này là một lần xóa và một lần chèn.

Quy tắc

Đưa ra hai chuỗi đầu vào (tuy nhiên được cung cấp thuận tiện trong ngôn ngữ của bạn), chương trình của bạn phải tìm khoảng cách chỉnh sửa tối thiểu giữa hai chuỗi.

Bạn có thể giả sử rằng các chuỗi chỉ chứa các ký tự A-Zvà có ít hơn 100 ký tự và nhiều hơn 0 ký tự.

Đây là mã golf , vì vậy giải pháp ngắn nhất sẽ thắng.

Các trường hợp thử nghiệm mẫu

ISLANDER, SLANDER
> 1
MART, KARMA
> 5
KITTEN, SITTING
> 5
INTENTION, EXECUTION
> 8

Tôi đã làm điều này trong excel trong lớp thuật toán của tôi một lần. Thật thú vị khi biến dự án thành một tài liệu .xls. Nó thực sự hoạt động khá tốt. Tôi sẽ xem nếu tôi có thể tìm thấy nó.
captncraig

PHP sẽ giành được điều này một cách dễ dàng.
st0le

@ st0le - Hàm tích hợp levenshteinxử lý các thay thế dưới dạng một chỉnh sửa (thay thế), không phải hai (xóa + chèn).
Ông Llama

Câu trả lời:


7

cân não, 2680

+>>>>>>>>>>>>>>>>>>>>>>++++++>,<[->-----<]>--[+++++++++++++++++++++
+++++++++++>>[->>+<<]>>+<<,--------------------------------]>>[-<<<
+>>>]<<<<[>[-<<+>>]<<<]>[-<<<<<+>>>>>]>[>>],----------[++++++++++>>
[->>+<<]>>+<<,----------]>>[-<<<+>>>]<<<<[>[-<<+>>]<<<]>[-<<+>>]<<[
-<+>>+<]<<<[->+<]>[-<+>>>>+<<<]>>>[-<+>]<[->+>+<<]<[-<+>]<[->+>+<<]
<[-<+>>+<]<[->+<]>>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>]<<[->>+
>+<<<]>>>[-<<<+>>>]<[->>+[->+>+<<]<<[->>+<<]>>]>>[-]<[<<]<<<+[->>>+
<<<]>>>[-<+<<+>>>]<<<<<[->>[->>>>[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>
+<<]>>>>]>>[->>>>+<<<<]>>>>[-<<<<+<<+>>>>>>]<<+[->>+<<]>>[-<<+<+>>>
]<<<<<<<<]>>[-]>>[-]>>[-]-[+<<-]+>>>>>>>>>>>>>>>>>[-<+>]<[->+<<<<+>
>>]<<<[->>>>>>[-<+>]<[->+<<<<+>>>]<<<<<<<[-]<<+>>>>>>[-<<<<+>>>>>>>
>>>[-<+>]<[->+>+<<]<<<<<<<<<[->+<]>[->>>>>>>>+<<<<<<<<<+>]<<<[->+<]
>[->>>>>>>>+<<<<<<<<<+>]>>>>>>>>>[-<<<<<+>>>>>]<<<<<[->>+>>>+<<<<<]
>>>>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>>>]<<<<<<+>>-
[-<<[-<<<<+>>>>]<<<<[->>+>>+<<<<]>>[->>>>>>[->>+<<]<<[->>+<<]<<[->>
+<<]<<[->>+<<]>>]>>>>]>>[->>+<<]>>[-<<+>>>>+<<]->>-[-[->>+<<]>>]>[-
>+<]>[-<+>>>+<<]<<<[->+<]>[-<+>>>+<<]+[->>[-<<+>>]>>[-<<+>>]<<<<<<+
]<<<<<<[->>>>>>+<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<[->>>>+<<<<]
-<<[-]>>>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<[->>[->>+<<]<<[->>+<<]>>]>>-[
-[->>+<<]>>]<[->+<]>[-<+>>>+<<]+[->>[-<<+>>]<<<<+]>>[-<<+>>]<<<<<<<
<-[+>>[-<<+>>]>>[-<<+>>]>>[-<<+>>]<<<<<<<<-]+>>>[-]<[->+<]>>>[-]<[-
>+<]>>>[-]<[->+<]>>>[->+<]>[-<+>>>>>>>>>>>>>+<<<<<<<<<<<<]>>>>>>>>>
>>>-[-[->>+<<]>>]>[->+<]>[-<+<+>>]<<<<-[+>>[-<<+>>]<<<<-]+>>[-<+>]>
>>>>>>>>[->+<]>[-<+>>>>>>>>>>>+<<<<<<<<<<]>>>>>[->+<]>[-<+>>>>>+<<<
<]>>>>-[-[->>+<<]>>]>[->+<]>[-<+<+>>]<<<<-[+>>[-<<+>>]<<<<-]+>[->-<
]>[-<[-]+>]<[->>>+<<<]>>>[-<<+<+>>>]<<-[+>[->+<]<]<[->>+<-[[-]>[->+
<]>[-<+>>>+<<]+>>[-<<[-]>>]<[->+<]>[-<+>>>+<<]+>>[-<<[-]>>]<[->+<]>
[-<+>>>+<<]+>>[-<<[-]>>]<<[-<<[-]+>>]<<[-<<[-]+>>]<<[-<<[-]+>>]<<<+
>->->>->>-<<<<<]<[->+<]]>[-<+>]>>[-<<<+>>>]<<<[->>>>>>>>>>>>>+<<<<<
<<<<<<<<]>>>>>>>>[->+<]>[-<+>>>>>>>>>+<<<<<<<<]>[->+<]>[-<+>>>>>>>>
>+<<<<<<<<]>>>>>>>>>[->>>+<<<]>>>[-<<+<+>>>]<<<<<[->>>>>+<<<<<]>>>>
>[-<<<<<+<<<+>>>>>>>>]<<<<<<<<+>>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]
<<[->>+<<]<<[->>+<<]>>>>>>>>>>]<<<<[-<<[-<<<<<<+>>>>>>]<<<<<<[->>+>
>>>+<<<<<<]>>[->>>>>>>>[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>
+<<]>>]>>>>>>]<<[-]<<[->>>>+<<<<]>>>>>>[-[->>+<<]<<[->>+<<]>>>>]<<[
->>>>>+<<<<<]-[+<<-]+>>>>>>>>>>>>>>>]<<]>>>>>>>>[->+<]<<[->+<]<<[->
+<]>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>]<<<<[->>[->>>>+<<<<]>>
>>[-<<+<<+>>>>]<<+[-[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>]<<<<]>>[-[->
>+<<]>>]>>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>[->-[>+>>]>
[+[-<+>]>+>>]<<<<<]>[-]<++++++[->++++++++[->+>+<<<<+>>]<]>>>.<.<<<.

Sử dụng lập trình động, tất nhiên.

Các chuỗi đầu vào phải được phân tách bằng khoảng trắng và theo sau là một dòng mới. Ví dụ:

INTENTION EXECUTION
008

1
Liên kết gọn gàng và rất dễ đọc - Tôi thích nó, +1!
Thomas

Đây có phải là ngôn ngữ máy tính không? : O

Đây là bài nộp khó hiểu nhất cho câu hỏi này ... +1 chỉ vì nó là BF.
HyperNeutrino

5

Con trăn, 138 148 152 ký tự

Ok, tôi biết nguyên tắc nhưng chưa bao giờ thực hiện khoảng cách chỉnh sửa trước đây, vì vậy hãy vào đây:

x,y=raw_input().split()
d=range(99)
for a in x:
 c=d;d=[d[0]+1]
 for b,p,q in zip(y,c[1:],c):d+=[min(d[-1]+1,p+1,q+2*(a!=b))]
print d[-1]

4

PHP, 40

Theo các quy tắc như đã nêu, nhưng không phải là tinh thần của các quy tắc:

<?=levenshtein($argv[1],$argv[2],1,2,1);

Có hai tham số làm đối số. Ví dụ gọi : php edit_dist.php word1 word2.
Thông thường levenshtein()coi sự thay thế là một thao tác, nhưng nó có dạng quá tải trong đó trọng số chèn / phụ / xóa có thể được chỉ định. Trong trường hợp này, 1/2/1 của nó.


3

APL (90 ký tự)

⊃⌽({h←1+c←⊃⍵⋄d←h,1↓⍵⋄h,(⊂⍵){y←⍵+1⋄d[y]←⍺{h⌷b=⍵⌷a:⍵⌷⍺⋄1+d[⍵]⌊y⌷⍺}⍵}¨⍳x}⍣(⊃⍴b←,⍞))0,⍳x←⍴a←,⍞

Tôi đang sử dụng Dyalog APL làm trình thông dịch của mình, ⎕IOđược đặt thành 1 và ⎕MLđược đặt thành 0. Hàm trực tiếp ( { ... }) tính toán, được đưa ra một hàng làm đầu vào, hàng tiếp theo trong ma trận khoảng cách. (Nó được bắt đầu với hàng ban đầu : 0,⍳x.) Toán tử power ( ) được sử dụng để lồng hàm một lần cho mỗi ký tự trong chuỗi thứ hai ( ⊃⍴b). Sau tất cả điều đó, hàng cuối cùng được đảo ngược ( ) và phần tử đầu tiên của nó được lấy ( ).

Thí dụ:

      ⊃⌽({h←1+c←⊃⍵⋄d←h,1↓⍵⋄h,(⊂⍵){y←⍵+1⋄d[y]←⍺{h⌷b=⍵⌷a:⍵⌷⍺⋄1+d[⍵]⌊y⌷⍺}⍵}¨⍳x}⍣(⊃⍴b←,⍞))0,⍳x←⍴a←,⍞
LOCKSMITH
BLACKSMITH
3
      ⊃⌽({h←1+c←⊃⍵⋄d←h,1↓⍵⋄h,(⊂⍵){y←⍵+1⋄d[y]←⍺{h⌷b=⍵⌷a:⍵⌷⍺⋄1+d[⍵]⌊y⌷⍺}⍵}¨⍳x}⍣(⊃⍴b←,⍞))0,⍳x←⍴a←,⍞
GATTTGTGACGCACCCTCAGAACTGCAGTAATGGTCCAGCTGCTTCACAGGCAACTGGTAACCACCTCATTTGGGGATGTTTCTGCCTTGCTAGCAGTGCCAGAGAGAACTTCATCATTGTCACCTCATCAAAGACTACTTTTTCAGACATCTCCTGTAG
AAGTACTGAACTCCTAATATCACCAATTCTTCTAAGTTCCTGGACATTGATCCGGAGGAGGATTCGCAGTTCAACATCAAGGTAAGGAAGGATACAGCATTGTTATCGTTGTTGAGATATTAGTAAGAAATACGCCTTTCCCCATGTTGTAAACGGGCTA
118

3

R 51

Điều này đọc thành hai dòng từ người dùng (là đầu vào) và sau đó chỉ cần sử dụng adistchức năng để tính khoảng cách. Vì chi phí thay thế là 2 cho vấn đề này, chúng tôi cần thêm một vectơ có tên cho tham số chi phí cho quảng cáo. Vì cũng có một tham số đếm cho adist, chúng tôi chỉ có thể rút ngắn chi phí cho cos nên chúng tôi vẫn có một kết quả khớp duy nhất cho các tên tham số.

x=readLines(n=2);adist(x[1],x[2],cos=c(i=1,d=1,s=2))

Ví dụ sử dụng

> x=readLines(n=2);adist(x[1],x[2],cos=c(i=1,d=1,s=2))
MART
KARMA
     [,1]
[1,]    5

0

Hồng ngọc 1.9, 124

l=->a,b{a[0]?b[0]?[(a[0]==b[0]?-1:1)+l[a[1..-1],b[1..-1]],l[a[1..-1],b],l[a,b[1..-1]]].min+1: a.size: b.size}
puts l[*ARGV]

Phiên bản chơi gôn của phương pháp Ruby chậm, đệ quy ở đây , được sửa đổi để tăng gấp đôi trọng lượng cho sự thay thế. Thực tế là phải mất 7 ký tự để loại bỏ ký tự đầu tiên của chuỗi thực sự gây tổn thương và thật tuyệt khi thay thế (a[0]==b[0]?-1:1)bằng một thứ như thế -1**a[0]<=>b[0]nhưng thứ tự các thao tác không phải là bạn của tôi.


0

Smalltalk (Smalltalk / X), 34

Tôi may mắn - lớp "Chuỗi" tiêu chuẩn đã chứa levenshtein:

đầu vào a, b:

a levenshteinTo:b s:2 k:2 c:1 i:1 d:1

(các tham số bổ sung cho phép các trọng số khác nhau thay thế, xóa, v.v.)

Chạy thử nghiệm:

#( 'ISLANDER'  'SLANDER' 
   'MART'      'KARMA'   
   'KITTEN'    'SITTING' 
   'INTENTION' 'EXECUTION'  
) pairWiseDo:[:a :b|
    a print. ' ' print. b print. ' ' print.
    (a levenshteinTo:b
            s:2 k:2 c:1 i:1 d:1) printCR.
].

->

ISLANDER SLANDER 1
MART KARMA 5
KITTEN SITTING 5
INTENTION EXECUTION 8
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.