Während es viele Bearbeitungsentfernungsfragen gibt, wie diese , gibt es keine einfache Frage, um ein Programm zu schreiben, das die Levenshtein-Entfernung berechnet.
Einige Exposition
Die Levenshtein bearbeiten Abstand zwischen zwei Saiten ist die minimal mögliche Anzahl von Einfügungen, Löschungen oder Ersetzungen, um ein Wort in ein anderes Wort umzuwandeln. In diesem Fall kostet jede Einfügung, Löschung und Ersetzung 1.
Der Abstand zwischen roll
und rolling
beträgt beispielsweise 3, da Löschvorgänge 1 kosten und 3 Zeichen gelöscht werden müssen. Der Abstand zwischen toll
undtall
beträgt 1, da Ersetzungen 1 kosten.
Regeln
- Die Eingabe besteht aus zwei Zeichenfolgen. Sie können davon ausgehen, dass die Zeichenfolgen in Kleinbuchstaben geschrieben sind, nur Buchstaben enthalten, nicht leer sind und maximal 100 Zeichen lang sind.
- Die Ausgabe ist die minimale Levenshtein-Bearbeitungsentfernung der beiden Zeichenfolgen, wie oben definiert.
- Ihr Code muss ein Programm oder eine Funktion sein. Es muss keine benannte Funktion sein, es kann sich jedoch nicht um eine integrierte Funktion handeln, die die Levenshtein-Entfernung direkt berechnet. Andere Einbauten sind erlaubt.
- Das ist Codegolf, also gewinnt die kürzeste Antwort.
Einige Beispiele
>>> lev("atoll", "bowl")
3
>>> lev("tar", "tarp")
1
>>> lev("turing", "tarpit")
4
>>> lev("antidisestablishmentarianism", "bulb")
27
Wie immer, wenn das Problem unklar ist, lassen Sie es mich bitte wissen. Viel Glück und gutes Golfen!
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 BytesDies ist eine einfache Implementierung dieser Formel:
Ungolfed:
quelle
Python 2,
151140138 BytesLangsame rekursive Implementierung der Levenshtein-Distanz basierend auf Wikipedia (Dank an @Kenney für die Rasur von 11 Zeichen und @ Sherlock9 für weitere 2).
Die richtigen Antworten für die vorgestellten Testfälle geben:
quelle
if !n*m:return n if n else m
, und weitere 2 Bytesreturn 1+min([ f(..), f(..), f(..) - (s[..] == t[..]) ])
.f(m-1,n-1)-(s[m-1]==t[n-1])
anstelle von verwendenf(m-1,n-1)+(s[m-1]!=t[n-1])-1
.JavaScript (ES6) 106
113 122Bearbeiten Sie 16 Bytes, die gemäß @Neil-Vorschlägen gespeichert wurden
Als anonyme Funktion.
Dies ist eine gelungene Implementierung des Wagner-Fischer-Algorithmus, genau wie im verlinkten Wikipedia-Artikel im Abschnitt Iterativ mit zwei Matrixzeilen beschrieben (auch wenn tatsächlich nur eine Zeile verwendet wird - Array w ).
Weniger golfen
Testschnipsel
quelle
[...[0,...t].keys()]
stattdessen verwenden? Spart 2 Bytes, wenn Sie können.[...[,...t].keys()]
funktioniert auch, denke ich.[...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 Bytes
Ein Golf dieser Lösung , aber es sieht nicht so aus, als wäre Willem schon seit einem Jahr dabei, also muss ich es selbst posten:
Versuchen Sie es mit repl.it
Nimmt zwei Zeichenketten und gibt den Abstand zu
STDOUT
( durch Meta erlaubt ) aus. Bitte kommentieren Sie Vorschläge, ich bin sicher, dies kann weiter golfen werden.quelle
input()
s oder ein verwendeninput().split()
?s
undt
irgendwo im Code definieren müssen. Keine Ursache. Gute Arbeit: Dm or n
. Sie können es durch ersetzenm+n
.AutoIt , 333 Bytes
Beispieltestcode:
Ausbeuten
quelle
k4, 66 Bytes
Ein langweiliges und im Grunde ungolfiertes Werkzeug der Algo. Ex.:
quelle
Im Ernst,
868278 BytesHex Dump:
Probieren Sie es online
(Beachten Sie, dass sich der Link auf eine andere Version bezieht, da einige Aspekte des Online-Interpreters von der neuen, kürzeren Version abweichen, obwohl dies mit dem herunterladbaren Interpreter problemlos funktioniert.)
Es geht um die einfachste Implementierung Ermöglicht ernsthaft die rekursive Definition. Es ist sehr langsam, weil es überhaupt keine Speicherung macht. Vielleicht könnte die tabellarische Methode kürzer sein (vielleicht durch die Verwendung der Register als Zeilen), aber ich bin ziemlich zufrieden damit, trotz der Unzulänglichkeiten, die die Sprache aufweist. Das kann man gebrauchen
als richtiger Funktionsaufruf mit zwei Argumenten war das ganz nett zu finden.
Erläuterung:
quelle
Python 3,
267216184162 BytesDiese Funktion berechnet die Levenshtein-Distanz unter Verwendung eines Arrays von
2 x len(word_2)+1
in der Größe ist.Bearbeiten: Dies kommt der Antwort von Willem's Python 2 nicht nahe, aber hier ist eine golfenere Antwort mit vielen kleinen Verbesserungen hier und da.
Ungolfed:
quelle
Retina ,
7872 BytesProbieren Sie es online!
In gewisser Weise handelt es sich hierbei um eine reine Regex-Lösung, bei der das Ergebnis die Anzahl der Positionen ist, an denen der Regex übereinstimmt. Weil warum nicht...
Faire Warnung, das ist super ineffizient. Das funktioniert so, dass die eigentliche Optimierung auf den Backtracker der Regex-Engine verlagert wird, der einfach alle möglichen Ausrichtungen erzwingt, wobei mit möglichst wenigen Änderungen begonnen wird und eine weitere zulässig ist, bis es möglich ist, die Zeichenfolgen mit Hinzufügungen, Löschungen und Ersetzungen abzugleichen .
Für eine etwas vernünftigere Lösung führt diese nur einmal das Matching durch und hat keine negativen Lookarounds. Hier ist das Ergebnis die Anzahl der Captures in der Gruppe
2
, auf die Siematch.Groups[2].Captures.Count
beispielsweise in C # zugreifen können . Es ist immer noch schrecklich ineffizient.Erläuterung
Ich erkläre die zweite Version oben, weil sie konzeptionell etwas einfacher ist (da es sich nur um ein einzelnes Regex-Match handelt). Hier ist eine ungolfed Version, in der ich die Gruppen benannt (oder nicht erfasst) und Kommentare hinzugefügt habe. Denken Sie daran, dass die Komponenten in einem Lookbehind von hinten nach vorne gelesen werden sollten, aber Alternativen und Lookaheads in diesen Komponenten sollten von vorne nach hinten gelesen werden. Ja.
Der einzige Unterschied zur 72-Byte-Version besteht darin, dass wir die führende
.+
(und die zweite Gruppe am Anfang) löschen können, indem wir Positionen am Ende finden, an denen wir nicht genug haben,<ops>
und alle diese Positionen zählen.quelle
Haskell ,
6764 BytesProbieren Sie es online! Anwendungsbeispiel:
"turing" # "tarpit"
Erträge4
.Erläuterung (für die vorherige 67-Byte-Version)
Dies ist eine rekursive Lösung. Bei zwei gegebenen Zeichenfolgen
e
undf
vergleichen wir zuerst die ersten Zeichena
undb
. Wenn sie gleich sind, ist der Levenshtein-Abstand vone
undf
derselbe wie der Levenshtein-Abstand vonr
unds
, der Rest vone
undf
nach dem Entfernen der ersten Zeichen. Andernfalls muss entwedera
oderb
entfernt werden, oder einer wird durch den anderen ersetzt.[r#f,e#s,r#s]
Berechnet rekursiv das Levenshtein für diese drei Fälle,minimum
wählt das kleinste aus und1
wird addiert, um den erforderlichen Vorgang zum Entfernen oder Ersetzen zu berücksichtigen.Wenn eine der Zeichenfolgen leer ist, befinden wir uns in der zweiten Zeile. In diesem Fall entspricht der Abstand lediglich der Länge der nicht leeren Zeichenfolge oder äquivalent der Länge beider miteinander verketteter Zeichenfolgen.
quelle
Python 3 ,
1059493 Bytes-11 Bytes von xnor
Golf-Version der kürzesten Implementierung auf Wikibooks .
Probieren Sie es online!
quelle
l=
muss eingeschlossen und gezählt werden, da die Funktion rekursiv ist. Sie können die Basenfälle zu kombinierenif b>""<a else len(a+b)
.Haskell, 136 Bytes
Rufen Sie an
e
. Etwas langsamantidisestablishmentarianism
usw.quelle
Jolf, 4 Bytes
Probieren Sie es hier aus!
Ich habe das gestern eingebaut, aber diese Herausforderung heute gesehen, also erst jetzt. Dennoch ist diese Antwort nicht konkurrierend.
In einer neueren Version:
Nimmt implizite zweite Eingabe.
quelle
GNU Prolog, 133 Bytes
Nimmt ein Tupel als Argument. Anwendungsbeispiel:
m
Gibt an, dassB
ist ,A
entweder direkt oder mit seinem ersten Zeichen entfernt.d
Verwendungenm
als ein Unterprogramm zur Berechnung eines Bearbeitungs Abstandes zwischen dem Tupel Elemente (dh des Abstandes von einer Reihe von Bearbeitungen man , daß umwandelt in die anderen). Dannl
ist ein Standardtrick zum Finden des Minimums vond
(Sie nehmen eine beliebige Strecke, dann nehmen Sie eine beliebige kleinere Strecke, wiederholen Sie, bis Sie nicht kleiner werden können).quelle
Perl,
168166163 BytesRekursive Implementierung. In a speichern
file.pl
und ausführen alsperl file.pl atoll bowl
.Die beiden anderen Implementierungen sind länger (vollständige Matrix: 237 Bytes,
zweieinzeilige Iterationen: 187).()
in Berufungl
.return
durch missbrauchdo
in trinary beseitigen.quelle
APL (Dyalog Classic) , 34 Byte
Probieren Sie es online!
quelle
C 192 Bytes
Detailliert
quelle
C #
215210198besser lesbar:
quelle
PowerShell v3 +, 247 Bytes
Am Ende habe ich das gemacht, um weitere Herausforderungen mit LDs zu lösen.
Codeerklärung mit Kommentaren.
quelle
JavaScript (ES6),
95 9189 BytesÜbernimmt die Eingabe als
(source)(target)
. Im Wesentlichen eine Portierung von @Willems Python-Antwort (später von @FlipTack optimiert ).Probieren Sie es online!
quelle