Meskipun ada banyak pertanyaan edit jarak, seperti ini , tidak ada pertanyaan sederhana untuk menulis sebuah program yang menghitung jarak Levenshtein.
Beberapa Eksposisi
Jarak edit Levenshtein antara dua string adalah jumlah penyisipan, penghapusan, atau penggantian minimum yang mungkin untuk mengubah satu kata menjadi kata lain. Dalam hal ini, setiap penyisipan, penghapusan dan penggantian memiliki biaya 1.
Misalnya, jarak antara roll
dan rolling
3, karena penghapusan berharga 1, dan kita perlu menghapus 3 karakter. Jarak antara toll
dan tall
1, karena biaya penggantian 1.
Aturan
- Input akan terdiri dari dua string. Anda dapat mengasumsikan bahwa string adalah huruf kecil, hanya berisi huruf, tidak kosong dan panjang maksimal 100 karakter.
- Outputnya adalah jarak edit Levenshtein minimum dari dua string, seperti yang didefinisikan di atas.
- Kode Anda harus berupa program atau fungsi. Itu tidak perlu menjadi fungsi bernama, tetapi tidak bisa menjadi fungsi bawaan yang secara langsung menghitung jarak Levenshtein. Built-in lainnya diizinkan.
- Ini kode golf, jadi jawaban tersingkat menang.
Beberapa contoh
>>> lev("atoll", "bowl")
3
>>> lev("tar", "tarp")
1
>>> lev("turing", "tarpit")
4
>>> lev("antidisestablishmentarianism", "bulb")
27
Seperti biasa, jika masalahnya tidak jelas, beri tahu saya. Semoga berhasil dan bermain golf dengan baik!
Katalog
var QUESTION_ID=67474;var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";var COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk";var OVERRIDE_USER=47581;var answers=[],answers_hash,answer_ids,answer_page=1,more_answers=true,comment_page;function answersUrl(index){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+index+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(index,answers){return"http://api.stackexchange.com/2.2/answers/"+answers.join(';')+"/comments?page="+index+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:true,success:function(data){answers.push.apply(answers,data.items);answers_hash=[];answer_ids=[];data.items.forEach(function(a){a.comments=[];var id=+a.share_link.match(/\d+/);answer_ids.push(id);answers_hash[id]=a});if(!data.has_more)more_answers=false;comment_page=1;getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:true,success:function(data){data.items.forEach(function(c){if(c.owner.user_id===OVERRIDE_USER)answers_hash[c.post_id].comments.push(c)});if(data.has_more)getComments();else if(more_answers)getAnswers();else process()}})}getAnswers();var SCORE_REG=/<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;var OVERRIDE_REG=/^Override\s*header:\s*/i;function getAuthorName(a){return a.owner.display_name}function process(){var valid=[];answers.forEach(function(a){var body=a.body;a.comments.forEach(function(c){if(OVERRIDE_REG.test(c.body))body='<h1>'+c.body.replace(OVERRIDE_REG,'')+'</h1>'});var match=body.match(SCORE_REG);if(match)valid.push({user:getAuthorName(a),size:+match[2],language:match[1],link:a.share_link,});else console.log(body)});valid.sort(function(a,b){var aB=a.size,bB=b.size;return aB-bB});var languages={};var place=1;var lastSize=null;var lastPlace=1;valid.forEach(function(a){if(a.size!=lastSize)lastPlace=place;lastSize=a.size;++place;var answer=jQuery("#answer-template").html();answer=answer.replace("{{PLACE}}",lastPlace+".").replace("{{NAME}}",a.user).replace("{{LANGUAGE}}",a.language).replace("{{SIZE}}",a.size).replace("{{LINK}}",a.link);answer=jQuery(answer);jQuery("#answers").append(answer);var lang=a.language;lang=jQuery('<a>'+lang+'</a>').text();languages[lang]=languages[lang]||{lang:a.language,lang_raw:lang.toLowerCase(),user:a.user,size:a.size,link:a.link}});var langs=[];for(var lang in languages)if(languages.hasOwnProperty(lang))langs.push(languages[lang]);langs.sort(function(a,b){if(a.lang_raw>b.lang_raw)return 1;if(a.lang_raw<b.lang_raw)return-1;return 0});for(var i=0;i<langs.length;++i){var language=jQuery("#language-template").html();var lang=langs[i];language=language.replace("{{LANGUAGE}}",lang.lang).replace("{{NAME}}",lang.user).replace("{{SIZE}}",lang.size).replace("{{LINK}}",lang.link);language=jQuery(language);jQuery("#languages").append(language)}}
body{text-align:left!important}#answer-list{padding:10px;width:290px;float:left}#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table>
Matlab,
177163 byteIni adalah implementasi langsung dari rumus ini:
Tidak Disatukan:
sumber
Python 2,
151140138 byteImplementasi rekursif lambat dari jarak Levenshtein berdasarkan Wikipedia (Terima kasih kepada @Kenney karena telah mencukur 11 karakter dan @ Sherlock9 untuk 2 yang lain).
Memberikan jawaban yang benar untuk kasus uji yang disajikan:
sumber
if !n*m:return n if n else m
, dan 2 lainnya olehreturn 1+min([ f(..), f(..), f(..) - (s[..] == t[..]) ])
.f(m-1,n-1)-(s[m-1]==t[n-1])
bukanf(m-1,n-1)+(s[m-1]!=t[n-1])-1
.JavaScript (ES6) 106
113 122Edit 16 byte yang disimpan mengikuti saran @Neil
Sebagai fungsi anonim.
Ini adalah implementasi golf dari algoritma Wagner-Fischer persis seperti yang dijelaskan dalam artikel wikipedia tertaut, di bagian Iterative dengan dua baris matriks (bahkan jika kenyataannya, hanya 1 baris digunakan - array w )
Kurang golf
Cuplikan tes
sumber
[...[0,...t].keys()]
? Menghemat 2 byte jika Anda bisa.[...[,...t].keys()]
menurut saya juga berfungsi.[...s].map()
:(s,t)=>(w=[...[,...t].keys()],[...s].map((u,i)=>w=w.map((v,j)=>p=j--?Math.min(p,v,w[j]-(s[i-1]==t[j]))+1:i)),p)
Python 2, 118 byte
Sebuah golf dari solusi ini , tetapi sepertinya Willem tidak ada selama setahun, jadi saya harus mempostingnya sendiri:
Coba di repl.it
Mengambil dua string dan menampilkan jarak ke
STDOUT
( diizinkan oleh meta ). Silakan komentar saran, saya yakin ini bisa golf lebih lanjut.sumber
input()
s atau satuinput().split()
?s
dant
di suatu tempat dalam kode. Sudahlah. Kerja bagus: Dm or n
. Anda bisa menggantinya denganm+n
.AutoIt , 333 byte
Kode uji sampel:
hasil panen
sumber
k4, 66 byte
Sebuah algo yang membosankan dan pada dasarnya tidak digubah. Ex.:
sumber
Serius,
868278 byteHex Dump:
Cobalah secara Online
(Perhatikan bahwa tautannya ke versi yang berbeda karena sesuatu tentang penerjemah online terputus dengan versi baru yang lebih pendek, meskipun itu berfungsi dengan baik dengan penerjemah yang dapat diunduh.)
Ini tentang implementasi yang paling mudah. Serius memungkinkan untuk definisi rekursif. Ini sangat lambat karena tidak ada memoisasi sama sekali. Mungkin metode tabular bisa lebih pendek (mungkin dengan menggunakan register sebagai baris), tapi saya cukup senang dengan ini, terlepas dari seberapa banyak kekurangan-kekurangan yang saya temukan. Yang itu bisa digunakan
sebagai panggilan fungsi dua argumen yang tepat adalah penemuan yang bagus.
Penjelasan:
sumber
Python 3,
267216184162 byteFungsi ini menghitung jarak Levenshtein menggunakan array yang
2 x len(word_2)+1
berukuran.Sunting: Ini tidak mendekati jawaban Python 2 Willem, tapi di sini ada jawaban yang lebih golf dengan banyak perbaikan kecil di sana-sini.
Tidak Disatukan:
sumber
Retina ,
7872 byteCobalah online!
Di satu sisi, ini adalah solusi regex murni di mana hasilnya adalah jumlah posisi yang cocok dengan regex. Karena kenapa tidak ...
Peringatan yang adil, ini sangat tidak efisien. Cara kerjanya adalah bahwa ia menurunkan optimasi yang sebenarnya ke backtracker mesin regex, yang dengan sederhana memaksa semua penyelarasan yang mungkin, mulai dengan perubahan sesedikit mungkin dan memungkinkan satu lagi sampai memungkinkan untuk mencocokkan string dengan penambahan, penghapusan dan penggantian. .
Untuk solusi yang sedikit lebih masuk akal, yang satu ini hanya cocok sekali dan tidak memiliki pencarian negatif. Di sini, hasilnya adalah jumlah tangkapan dalam grup
2
, yang dapat Anda akses denganmatch.Groups[2].Captures.Count
di C #, misalnya. Ini masih sangat tidak efisien.Penjelasan
Saya menjelaskan versi kedua di atas, karena secara konseptual sedikit lebih mudah (karena itu hanya satu pertandingan regex). Ini adalah versi yang tidak di-serigala yang saya beri nama grup (atau membuat mereka tidak menangkap) dan menambahkan komentar. Ingat bahwa komponen dalam tampilan harus dibaca dari belakang ke depan, tetapi alternatif dan tampilan di dalam itu harus dibaca dari depan ke belakang. Ya.
Satu-satunya perbedaan pada versi 72-byte adalah bahwa kita dapat melepaskan yang terdepan
.+
(dan grup kedua di awal) dengan menemukan posisi di akhir di mana kita tidak memiliki cukup<ops>
dan menghitung semua posisi itu.sumber
Haskell ,
6764 byteCobalah online! Contoh penggunaan:
"turing" # "tarpit"
hasil4
.Penjelasan (untuk versi 67 byte sebelumnya)
Ini adalah solusi rekursif. Diberikan dua string
e
danf
, pertama-tama kita membandingkan karakter pertamaa
danb
. Jika mereka sama, maka jarak Levenshteine
danf
sama dengan jarak Levenshteinr
dans
, sisae
danf
setelah menghapus karakter pertama. Kalau tidak, salah satua
ataub
perlu dihapus, atau satu diganti dengan yang lain.[r#f,e#s,r#s]
secara rekursif menghitung Levenshtein untuk ketiga kasus tersebut,minimum
mengambil yang terkecil, dan1
ditambahkan ke akun untuk operasi pemindahan atau penggantian yang diperlukan.Jika salah satu senarnya kosong, kita naik ke baris kedua. Dalam hal ini, jaraknya hanya panjang dari string yang tidak kosong, atau setara dengan panjang dari kedua string yang disatukan.
sumber
Python 3 ,
1059493 byte-11 byte oleh xnor
Versi golf dari implementasi tersingkat di Wikibooks .
Cobalah online!
sumber
l=
kebutuhan untuk dimasukkan dan dihitung karena fungsi rekursif. Anda dapat menggabungkan kasus basis keif b>""<a else len(a+b)
.Haskell, 136 byte
Panggil
e
. Agak lambatantidisestablishmentarianism
dll.sumber
Jolf, 4 byte
Coba di sini!
Saya menambahkan bahwa builtin kemarin, tetapi melihat tantangan ini hari ini, yaitu, baru saja. Namun, jawaban ini tidak bersaing.
Dalam versi yang lebih baru:
mengambil input kedua implisit.
sumber
GNU Prolog, 133 byte
Mengambil tuple sebagai argumen. Contoh penggunaan:
m
Menentukan bahwaB
adalahA
baik secara langsung maupun dengan karakter pertama dihapus.d
kegunaanm
sebagai sebuah sub rutin untuk menghitung suatu mengedit jarak antara unsur-unsur tuple (yaitu jarak dari serangkaian suntingan yang mengubah satu ke yang lain). Kemudianl
adalah trik standar untuk menemukan minimumd
(Anda mengambil jarak sewenang-wenang, kemudian mengambil jarak lebih kecil sewenang-wenang, ulangi sampai Anda tidak bisa pergi lebih kecil).sumber
Perl,
168166163 byteImplementasi rekursif. Simpan di
file.pl
dan jalankan sebagaiperl file.pl atoll bowl
.Dua implementasi lainnya keduanya lebih panjang (matriks penuh: 237 byte,
duaiteratif satu baris: 187).()
dalam panggilanl
.return
dengan menyalahgunakando
dalam trinary.sumber
APL (Dyalog Classic) , 34 byte
Cobalah online!
sumber
C, 192 byte
Terperinci
sumber
C #,
215210198lebih mudah dibaca:
sumber
PowerShell v3 +, 247 Bytes
Saya akhirnya membuat ini untuk memecahkan tantangan lain yang melibatkan LD.
Penjelasan kode dengan komentar.
sumber
JavaScript (ES6),
95 9189 byteMengambil input sebagai
(source)(target)
. Pada dasarnya sebuah port jawaban @ Willem's Python (kemudian dioptimalkan oleh @FlipTack ).Cobalah online!
sumber