Temukan jarak edit minimum antara dua string

13

Penjelasan

The mengedit jarak antara dua string adalah fungsi dari jumlah minimum yang mungkin insersi, delesi, atau substitusi untuk mengkonversi satu kata ke kata lain.

Penyisipan dan penghapusan biaya 1, dan biaya penggantian 2.

Misalnya, jarak antara ABdan Aadalah 1, karena penghapusan biaya 1 dan satu-satunya pengeditan yang diperlukan adalah penghapusan Bkarakter.

Jarak antara CARdan FARadalah 2, karena biaya penggantian 2. Cara lain untuk melihat ini adalah satu penghapusan dan satu penyisipan.

Aturan

Diberikan dua string input (disediakan namun nyaman dalam bahasa Anda), program Anda harus menemukan jarak edit minimum antara dua string.

Anda dapat mengasumsikan bahwa string hanya berisi karakter A-Zdan memiliki kurang dari 100 karakter dan lebih dari 0 karakter.

Ini kode golf , jadi solusi terpendek menang.

Contoh Uji Kasus

ISLANDER, SLANDER
> 1
MART, KARMA
> 5
KITTEN, SITTING
> 5
INTENTION, EXECUTION
> 8
Peter Olson
sumber
Saya melakukan ini di excel di kelas algoritma saya sekali. Agak menyenangkan untuk mengubah proyek sebagai dokumen .xls. Ini sebenarnya bekerja cukup baik. Saya akan melihat apakah saya dapat menemukannya.
captncraig
PHP seharusnya memenangkan ini dengan mudah.
st0le
@ st0le - Fungsi bawaan levenshteinmemperlakukan substitusi sebagai satu edit (pengganti), bukan dua (delete + insert).
Tn. Llama

Jawaban:

7

brainfuck, 2680

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

Menggunakan pemrograman dinamis, tentu saja.

String input harus dipisahkan oleh spasi, dan diikuti oleh baris baru. Sebagai contoh:

INTENTION EXECUTION
008
kotak kardus
sumber
1
Selaras rapi dan sangat mudah dibaca - Saya menyukainya, +1!
Thomas
Apakah ini bahasa komputer? : O
Ini adalah pengiriman yang paling membingungkan untuk pertanyaan ini ... +1 hanya karena BF.
HyperNeutrino
5

Python, 138 148 152 karakter

Ok, saya tahu prinsipnya tetapi belum pernah mengimplementasikan edit distance sebelumnya, jadi begini:

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]
han
sumber
4

PHP, 40

Mengikuti aturan sebagaimana dinyatakan, tetapi tidak semangat aturan:

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

Membawa dua parameter sebagai argumen. Contoh memanggil: php edit_dist.php word1 word2.
Biasanya levenshtein()menganggap substitusi sebagai satu operasi, tetapi memiliki bentuk kelebihan tempat bobot insert / sub / delete dapat ditentukan. Dalam hal ini, 1/2/1.

Tuan Llama
sumber
3

APL (90 karakter)

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

Saya menggunakan Dyalog APL sebagai juru bahasa saya, dengan ⎕IOset ke 1 dan ⎕MLset ke 0. Fungsi langsung ( { ... }) menghitung, diberi baris sebagai input, baris berikutnya dalam matriks jarak. (Dimulai dengan baris awal:. 0,⍳x) Operator daya ( ) digunakan untuk membuat sarang fungsi sekali untuk setiap karakter dalam string kedua ( ⊃⍴b). Setelah semua itu, baris terakhir dibalik ( ), dan elemen pertamanya diambil ( ).

Contoh:

      ⊃⌽({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
Dillon Cower
sumber
3

R 51

Ini dibaca dalam dua baris dari pengguna (yang merupakan input) dan kemudian hanya menggunakan adistfungsi untuk menghitung jarak. Karena biaya pengganti 2 untuk masalah ini, kita perlu menambahkan vektor bernama untuk parameter biaya untuk adist. Karena ada juga parameter jumlah untuk adist, kami hanya dapat mempersingkat biaya menjadi cos sehingga kami masih memiliki kecocokan unik untuk nama parameter.

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

Contoh penggunaan

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

Ruby 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]

Versi Golf dari metode Ruby rekursif yang lambat di sini , dimodifikasi untuk menggandakan bobot penggantian. Fakta bahwa dibutuhkan 7 karakter untuk menghapus karakter pertama dari string benar-benar menyakitkan, dan itu akan keren untuk diganti (a[0]==b[0]?-1:1)dengan sesuatu seperti -1**a[0]<=>b[0]tetapi urutan operasinya bukan teman saya.

histokrat
sumber
0

Smalltalk (Smalltalk / X), 34

Saya beruntung - kelas "String" standar sudah berisi levenshtein:

masukan a, b:

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

(parameter tambahan memungkinkan untuk bobot yang berbeda pada substitusi, penghapusan, dll.)

Uji coba:

#( '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
blabla999
sumber