레 벤슈 테인 거리


40

같은 많은 편집 거리 질문이 있지만 이 하나 의 Levenshtein 거리를 계산하는 프로그램을 작성하는 간단한 문제가 아니다.

일부 박람회

두 문자열 사이의 Levenshtein 편집 거리는 한 단어를 다른 단어로 변환하기위한 가능한 최소 삽입, 삭제 또는 대체 수입니다. 이 경우 각 삽입, 삭제 및 대체 비용은 1입니다.

예를 들어, 삭제 비용이 1이고 3 개의 문자를 삭제해야하기 때문에 roll와 사이의 거리는 rolling3입니다. 대체 비용이 1이기 때문에 toll와 사이의 거리는 tall1입니다.

규칙

  • 입력은 두 개의 문자열입니다. 문자열은 소문자이고 문자 만 포함하며 비어 있지 않으며 최대 100 자라고 가정 할 수 있습니다.
  • 출력은 위에서 정의한 것처럼 두 문자열의 최소 레 벤슈 테인 편집 거리가됩니다.
  • 코드는 프로그램이나 기능이어야합니다. 명명 된 함수일 필요는 없지만 Levenshtein 거리를 직접 계산하는 내장 함수일 수는 없습니다. 다른 내장 기능도 허용됩니다.
  • 이것은 코드 골프이므로 최단 답변이 이깁니다.

일부 예

>>> lev("atoll", "bowl")
3
>>> lev("tar", "tarp")
1
>>> lev("turing", "tarpit")
4
>>> lev("antidisestablishmentarianism", "bulb")
27

문제가 명확하지 않은 경우 언제든지 알려주십시오. 행운과 좋은 골프!

목록

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>

답변:


8

Pyth, 34 바이트

J]wf}z=Jsmsm++.DdkXLdkGXLkdGhld-Jk

데모

이것은 특히 골프는 아니지만 매우 느립니다. 합리적인 기간 동안 2 번 이상의 변경 사항을 처리 할 수 ​​없습니다.


3
그러나 그것은 효과가 있으며 그것이 중요합니다. : P
Conor O'Brien

10

Matlab, 177163 바이트

function l=c(a,b);m=nnz(a)+1;n=nnz(b)+1;for i=0:m-1;for j=0:n-1;z=max(i,j);try;z=min([l(i,j+1)+1,l(i+1,j)+1,l(i,j)+(a(i)~=b(j))]);end;l(i+1,j+1)=z;end;end;l=l(m,n)

이것은이 공식의 간단한 구현입니다.

여기에 이미지 설명을 입력하십시오

언 골프 드 :

function l=l(a,b);
m=nnz(a)+1;
n=nnz(b)+1;
for i=0:m-1;
    for j=0:n-1;
        z=max(i,j);
        try;
            z=min([l(i,j+1)+1,l(i+1,j)+1,l(i,j)+(a(i)~=b(j))]);
        end;
        l(i+1,j+1)=z;
    end;
end;
l=l(m,n)

스코어링 된 코드가 포함되지 않은 경우 스코어링 된 코드를 포함하십시오. 그렇지 않으면 골프를 칠 수 있는 많은 공백이 있다고 생각 합니다.
Alex A.

1
@AlexA. 들여 쓰기 목적을위한 선행 공간과 줄 바꿈은 계산되지 않으며 안전하게 제거 할 수 있습니다. 시간이지나면서 이것은 허락되었고 아무도 불평하지 않았다.
edc65

1
@ edc65 이제 메타 합의 는 점수가 매겨진 코드를 제공해야한다는 것입니다.
Alex A.

2
그렇다면 대다수 는 읽을 수없는 버전을 선호합니다. 누군가가 실제로 무슨 일이 일어나고 있는지보고 싶을 때를 대비하여 여전히 읽을 수있는 버전을 여기에
보냈습니다.

2
골프 제출 (점수를받은 것)과 비 골프 버전을 모두 제공하는 것이 일반적입니다. 점수를 매긴 것만 포함하면됩니다. ;)
Alex A.

7

파이썬 2 151 140 138 바이트

Wikipedia를 기반으로 한 Levenshtein 거리의 느린 재귀 구현 (11 문자를 면도하면 @Kenney, 2 개는 @ Sherlock9).

def l(s,t):
 def f(m,n):
  if m*n<1:return m or n
  return 1+min([f(m-1,n),f(m,n-1),f(m-1,n-1)-(s[m-1]==t[n-1])])
 return f(len(s),len(t))

제시된 테스트 사례에 대한 정답 제공 :

assert l("tar", "tarp") == 1
assert l("turing", "tarpit") == 4
assert l("antidisestablishmentarianism", "bulb") == 27        
assert l("atoll", "bowl") == 3

1
와 같은 작업을 수행 if !n*m:return n if n else m하고 다른 2 by를 사용 하여 3-4 바이트 정도를 절약 할 수 있습니다 return 1+min([ f(..), f(..), f(..) - (s[..] == t[..]) ]).
Kenney

f(m-1,n-1)-(s[m-1]==t[n-1])대신을 사용하여 2 바이트를 절약 할 수 f(m-1,n-1)+(s[m-1]!=t[n-1])-1있습니다.
Sherlock9


5

자바 스크립트 (ES6) 106 113 122

@Neil 제안에 따라 저장된 16 바이트 편집

익명의 기능으로.

(s,t)=>[...s].map((u,i)=>w=w.map((v,j)=>p=j--?Math.min(p,v,w[j]-(u==t[j]))+1:i+1),w=[...[,...t].keys()])|p

이것은 링크 된 Wikipedia 기사의 두 매트릭스 행 반복 섹션 (실제로 단 1 개의 행만 사용 하더라도 배열 w )에 설명 된대로 Wagner–Fischer 알고리즘을 구현 한 것입니다.

덜 골프

(s,t)=>
{
  w = [...[0,...t].keys()];
  for(i = 0; i < s.length; i++)
    w = w.map((v,j)=>
              p = j
              ? Math.min(p+1, v+1, w[j-1] + (s[i]!=t[j-1]))
              : i+1
             );
  return p
}

테스트 스 니펫

L=(s,t)=>[...s].map((u,i)=>w=w.map((v,j)=>p=j--?Math.min(p,v,w[j]-(u==t[j]))+1:i+1),w=[...[,...t].keys()])|p

console.log=x=>O.textContent+=x+'\n';

[["atoll", "bowl"],["tar", "tarp"]
,["turing", "tarpit"],["antidisestablishmentarianism", "bulb"]]
.forEach(t=>console.log(t+' => '+L(...t)))
<pre id=O></pre>


1
[...[0,...t].keys()]대신 사용할 수 있습니까 ? 가능한 경우 2 바이트를 저장합니다.
Neil

1
못생긴 것처럼 보이는 @Neil이지만 더 짧습니다. Thx
edc65

1
실제로 다른 바이트를 저장할 수 있고 [...[,...t].keys()]작동한다고 생각합니다.
Neil

나는 다음을 사용하여 다른 바이트를 제거 할 수 있었다 [...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)
Neil

@Neil great, 다시 한번 감사합니다!
edc65

4

파이썬 2, 118 바이트

이 솔루션 의 골프 이지만 Willem이 1 년 동안 있었던 것처럼 보이지 않으므로 직접 게시해야합니다.

def l(s,t):f=lambda m,n:m or n if m*n<1else-~min(f(m-1,n),f(m,n-1),f(m-1,n-1)-(s[m-1]==t[n-1]));print f(len(s),len(t))

repl.it 에보십시오

두 개의 문자열을 가져 와서 거리를 출력합니다 STDOUT( meta에 의해 허용됨 ). 의견을 말 해주세요. 골프를 더 할 수 있다고 확신합니다.


모든 것을 함수로 감싸 야합니까? 두 개 input()또는 input().split()? 를 사용할 수 있습니까?
Sherlock9

@ Sherlock9 나는 그것을 시도했지만 내가 말할 수있는 한 1 바이트 추가 비용이 든다.
FlipTack

그래, 난 당신이 정의 할 필요가 있음을 잊어 st코드에서 어딘가에. 신경 쓰지 마. 잘 했어 : D
Sherlock9

Willem이 왜 사용했는지 잘 모르겠습니다 m or n. 로 바꿀 수 있습니다 m+n.
Arnauld

3

AutoIt , 333 바이트

Func l($0,$1,$_=StringLen,$z=StringMid)
Dim $2=$_($0),$3=$_($1),$4[$2+1][$3+1]
For $5=0 To $2
$4[$5][0]=$5
Next
For $6=0 To $3
$4[0][$6]=$6
Next
For $5=1 To $2
For $6=1 To $3
$9=$z($0,$5,1)<>$z($1,$6,1)
$7=1+$4[$5][$6-1]
$8=$9+$4[$5-1][$6-1]
$m=1+$4[$5-1][$6]
$m=$m>$7?$7:$m
$4[$5][$6]=$m>$8?$8:$m
Next
Next
Return $4[$2][$3]
EndFunc

샘플 테스트 코드 :

ConsoleWrite(l("atoll", "bowl") & @LF)
ConsoleWrite(l("tar", "tarp") & @LF)
ConsoleWrite(l("turing", "tarpit") & @LF)
ConsoleWrite(l("antidisestablishmentarianism", "bulb") & @LF)

수확량

3
1
4
27

3

k4, 66 바이트

{$[~#x;#y;~#y;#x;&/.z.s'[-1 0 -1_\:x;0 -1 -1_\:y]+1 1,~(*|x)=*|y]}

지루하고 기본적으로 ungolfed algo의 impl. 전의.:

  f:{$[~#x;#y;~#y;#x;&/.z.s'[-1 0 -1_\:x;0 -1 -1_\:y]+1 1,~(*|x)=*|y]}
  f["kitten";"sitting"]
3
  f["atoll";"bowl"]
3
  f["tar";"tarp"]
1
  f["turing";"tarpit"]
4
  f["antidisestablishmentarianism";"bulb"]
27

3

진심으로 86 82 78 bytes

,#,#`k;;;░="+l"£@"│d);)[]oq╜Riu)@d);)@[]oq╜Riu(@)@)@[]oq╜Ri3}@)=Y+km"£@IRi`;╗ƒ

육각 덤프 :

2c232c23606b3b3b3bb03d222b6c229c4022b364293b295b5d6f71bd526975294064293b29405b
5d6f71bd5269752840294029405b5d6f71bd5269337d40293d592b6b6d229c40495269603bbb9f

온라인으로 사용해보십시오

다운로드 가능한 인터프리터에서 제대로 작동하더라도 온라인 인터프리터에 대한 새롭고 짧은 버전으로 인해 링크가 다른 버전에 링크되어 있습니다.

가장 간단한 구현에 관한 것입니다. 재귀 적 정의를 심각하게 허용합니다. 메모가 전혀 없으므로 매우 느립니다. 아마도 테이블 형식 방법은 더 짧을 수도 있지만 (레지스터를 행으로 사용하여) 어쩌면 여기에 포함 된 kludging-my-way-around-the-language의 단점에도 불구하고 상당히 만족합니다. 사용할 수있는

[]oq`<code>`Ri

적절한 두 개의 인수 함수 호출로 아주 좋은 발견이었습니다.

설명:

,#,#                             Read in two arguments, break them into lists of chars
    `                       `;╗ƒ put the quoted function in reg0 and immediately call it
     k;;;                        put the two lists in a list and make 3 copies
         ░                       replace the latter two with one with empty lists removed
          =                      replace two more with 1 if no empty lists removed, else 0
           "..."£@"..."£@        push the two functions described below, moving 
                                 the boolean above them both
                         I       select the correct function based on the condition
                          Ri     call the function, returning the correct distance
                                 for these substrings

   There are two functions that can be called from the main function above. Each expects 
   two strings, i and j, to be on the stack. This situation is ensured by putting 
   those strings in a list and using R to call the functions with that list as the stack.
   The first is very simple:

+l                             Concatenate the strings and take their length.
                               This is equivalent to the length of the longer
                               string, since one of the strings will be empty.

   The second function is very long and complicated. It will do the "insertion, deletion, 
   substitution" part of the recursive definition. Here's what happens in 4 parts:

│d);)                          After this, the stack is top[i-,j,i,j,ci,i-], where i- is 
                               list i with its last character, ci, chopped off.
     []oq                      this puts i- and j into a list so that they can be passed
                               as arguments recursively into the main function
         ╜Riu                  this calls the main function (from reg0) with the args
                               which will return a number to which we add 1 to get #d,
                               the min distance if we delete a character
)@d);)@                        After this, the stack is top[i,j-,ci,i-,#d,cj,j-], where 
                               j- and cj are the same idea as i- and ci
       []oq╜Riu                listify arguments, recurse and increment to get #i
                               (distance if we insert)
(@)@)@                         After this, the stack is top[i-,j-,#d,cj,#i,ci]
      []oq╜Ri                  listify arguments, recurse to get min distance between 
                               them but we still need to add 1 when we'd need to 
                               substitute because the chars we chopped off are different
(((@)                          After this, the stack is top[cj,ci,#s,#d,#i]
     =Y                        1 if they are not equal, 0 if they are
       +                       add it to the distance we find to get the distance
                               if we substitute here
        k                      put them all in a list
         m                     push the minimum distance over the three options

코드가 사전 요소를 이스케이프 처리하는 방법을 좋아합니다.
mınxomaτ

3

파이썬 3 267 216 184 162 바이트

이 함수 2 x len(word_2)+1는 크기 가 큰 배열을 사용하여 Levenshtein 거리를 계산합니다 .

편집 : 이것은 Willem의 Python 2 답변에 가깝지는 않지만 여기에 약간의 세밀한 수정이있는 더 골프화 된 답변이 있습니다.

def e(p,q):
 m=len(q);r=range;*a,=r(m+1);b=[1]*-~m
 for i in r(len(p)):
  for j in r(m):b[j+1]=1+min(a[j+1],b[j],a[j]-(p[i]==q[j]))
  a,b=b,[i+2]*-~m
 return a[m]

언 골프 드 :

def edit_distance(word_1,word_2):
    len_1 = len(word_1)
    len_2 = len(word_2)
    dist = [[x for x in range(len_2+1)], [1 for y in range(len_2+1)]]
    for i in range(len_1):
        for j in range(len_2):
            if word_1[i] == word_2[j]:
                dist[1][j+1] = dist[0][j]
            else:
                deletion = dist[0][j+1]+1
                insertion = dist[1][j]+1
                substitution = dist[0][j]+1
                dist[1][j+1] = min(deletion, insertion, substitution)
        dist[0], dist[1] = dist[1], [i+2 for m in range(len_2+1)]
    return dist[0][len_2]

3

망막 , 78 72 바이트

&`(.)*$(?<!(?=((?<-4>\4)|(?<-1>.(?<-4>)?))*,(?(4),))^.*,((.)|(?<-1>.))*)

온라인으로 사용해보십시오!

어떤 방식으로, 이것은 정규식 솔루션이며 결과는 정규식과 일치하는 위치 수입니다. 왜 안돼?

공정한 경고, 이것은 매우 비효율적입니다. 이것이 작동하는 방식은 정규 최적화 엔진의 백 트래커에 실제 최적화를 오프로드하는 것입니다. 정규식은 가능한 한 적은 변경으로 시작하여 가능한 모든 정렬을 강제하고 추가, 삭제 및 대체로 문자열을 일치시킬 수있을 때까지 한 번 더 허용합니다. .

약간 더 합리적인 솔루션의 경우이 솔루션 은 한 번만 일치하며 부정적인 예측 방법이 없습니다. 여기서 결과는 group의 캡처 수이며 , 예를 들어 C #에서 2액세스 할 수 있습니다 match.Groups[2].Captures.Count. 그래도 여전히 비효율적입니다.

설명

위의 두 번째 버전을 설명하고 있습니다. 단순히 단일 정규식 일치이기 때문에 개념적으로 조금 더 쉽습니다. 다음은 그룹 이름을 지정하거나 캡처하지 않은 주석이없는 버전입니다. lookbehind의 구성 요소는 앞뒤로 읽어야하지만, 그 안의 대안 및 lookahead는 앞뒤로 읽어야합니다. 네.

.+                      # Ensures backtracking from smallest to largest for next repetition
(?<ops>(?<distance>.))* # This puts the current attempted distances onto two different stacks,
                        # one to work with, and one for the result.
$                       # Make sure the lookbehind starts from the end.
(?<=                    # The basic idea is now to match up the strings character by character,
                        # allowing insertions/deletions/substitutions at the cost of one capture
                        # on <ops>. Remember to read from the bottom up.
  (?=                   # Start matching forwards again. We need to go through the other string
                        # front-to-back due to the nature of the stack (the last character we
                        # remembered from the second string must be the first character we check
                        # against in the first string).
    (?:
      (?<-str>\k<str>)  # Either match the current character against the corresponding one from
                        # the other string.
    |
      (?<-ops>          # Or consume one operation to...
        .               # consume a character without matching it to the other string (a deletion)
        (?<-str>)?      # optionally dropping a character from the other string as well 
                        # (a substitution).
      )
    )*                  # Rinse and repeat.
    ,(?(str),)          # Ensure we reached the end of the first string while consuming all of the 
                        # second string. This is only possible if the two strings can be matched up 
                        # in no more than <distance> operations.
  )
  ^.*,                  # Match the rest of string to get back to the front.
  (?:                   # This remembers the second string from back-to-front.
    (?<str>.)           # Either capture the current character.
  |
    (?<-ops>.)          # Or skip it, consuming an operation. This is an insertion.
  )*
)

72 바이트 버전과의 유일한 차이점은 우리 가 충분 하지 않은.+ 끝에 위치를 찾아서 그 위치를 모두 계산 하여 선두 (및 처음에 두 번째 그룹)를 삭제할 수 있다는 것 입니다.<ops>


3

하스켈 , 67 64 바이트

e@(a:r)#f@(b:s)=sum[1|a/=b]+minimum[r#f,e#s,r#s]
x#y=length$x++y

온라인으로 사용해보십시오! 사용법 예 : "turing" # "tarpit"yields 4.


설명 (이전 67 바이트 버전의 경우)

e@(a:r)#f@(b:s)|a==b=r#s|1<3=1+minimum[r#f,e#s,r#s]
x#y=length$x++y

이것은 재귀 솔루션입니다. 두 문자열을 감안 e하고 f, 우리는 먼저 첫 문자를 비교 a하고 b. 이들이 동일하면 Levenshtein 거리 e와의 거리는 Levenshtein 거리 및와 f동일 r하며 s, 나머지 는 첫 문자를 제거한 후 e와 같습니다 f. 그렇지 않은 경우 a또는 b제거해야하거나 하나가 다른 것으로 대체됩니다. [r#f,e#s,r#s]이 세 가지 경우에 대해 레 벤슈 테인을 재귀 적으로 계산하고 minimum가장 작은 것을 선택 1하고 필요한 제거 또는 교체 작업을 설명하기 위해 추가됩니다.

문자열 중 하나가 비어 있으면 두 번째 줄에 올라갑니다. 이 경우, 거리는 비어 있지 않은 문자열의 길이이거나 두 문자열의 길이와 함께 연결됩니다.


1
와우, 이것은 정말 우아하고 짧은 매우 좋은 솔루션입니다.
ggPeti

3

파이썬 3 , 105 94 93 바이트

xnor에 의해 -11 바이트

l=lambda a,b:b>""<a and min(l(a[1:],b[1:])+(a[0]!=b[0]),l(a[1:],b)+1,l(a,b[1:])+1)or len(a+b)

Wikibooks 에서 가장 짧은 구현의 골프 버전 .

온라인으로 사용해보십시오!


좋은 해결책. l=요구는 포함 함수가 재귀 때문에 계산한다. 기본 사례를에 결합 할 수 있습니다 if b>""<a else len(a+b).
xnor

운영자와 좋은 플레이, 고맙습니다!
movatica

2

하스켈, 136 바이트

전화하십시오 e. 비트가 느려짐 antidisestablishmentarianism

l=length
e a b=v a(l a)b(l b)
v a i b j|i*j==0=i+j|0<1=minimum[1+v a(i-1)b j,1+v a i b(j-1),fromEnum(a!!(i-1)/=b!!(j-1))+v a(i-1)b(j-1)]

2

Jolf, 4 바이트

여기 사용해보십시오!

~LiI
~L   calculate the Levenshtein distance of
  i   input string
   I  and another input string

나는 어제 그 내장을 추가했지만 오늘, 즉 지금 당장이 도전을 보았습니다. 그럼에도 불구 하고이 답변은 경쟁이 아닙니다.

최신 버전에서 :

~Li

암시 적 두 번째 입력을받습니다.


" 코드는 프로그램 또는 함수 여야합니다. 명명 된 함수일 필요는 없지만 Levenshtein 거리를 직접 계산하는 내장 함수일 수는 없습니다 . 다른 내장 함수 도 허용됩니다. "
Kevin Cruijssen

아, 당신은 그것이 경쟁이 아니라고 언급하지 않았습니다. 제목에 넣거나 내장없이 유효한 프로그램 / 기능을 추가하는 것이 좋습니다.
Kevin Cruijssen

2

GNU 프롤로그, 133 바이트

m([H|A],B):-B=A;B=[H|A].
d([H|A]-[H|B],D):-d(A-B,D).
d(A-B,D):-A=B,D=0;D#=E+1,m(A,X),m(B,Y),d(X-Y,E).
l(W,D):-d(W,D),(E#<D,l(W,E);!).

튜플을 인수로 사용합니다. 사용 예 :

| ?- l("turing"-"tarpit",D).

D = 4

yes

m지정 BA직접 또는 첫 문자 제거. d사용 m서브 루틴으로 계산할 튜플 요소 사이의 거리를 수정 (편집 일련의 거리 즉, 그 변환에 다른 하나). 그런 다음 최소값을 찾기위한 표준 트릭입니다 (임의의 거리를 취한 다음 임의의 더 작은 거리를 취하고 더 작아 질 수 없을 때까지 반복하십시오).ld


1

168 166 163 바이트

sub l{my($S,$T,$m)=(@_,100);$S*$T?do{$m=++$_<$m?$_:$m for l($S-1,$T),l($S,--$T),l(--$S,$T)-($a[$S]eq$b[$T]);$m}:$S||$T}print l~~(@a=shift=~/./g),~~(@b=shift=~/./g)

재귀 적 구현. 에 저장 file.pl하고로 실행 하십시오 perl file.pl atoll bowl.

sub l {
    my($S,$T,$m)=(@_,100);

    $S*$T
    ? do {
        $m = ++$_ < $m ? $_ : $m
        for
            l($S-1,   $T),
            l($S  , --$T),
            l(--$S,   $T) - ($a[$S] eq $b[$T])
        ;    
        $m
    }
    : $S||$T
}
print l~~(@a=shift=~/./g),~~(@b=shift=~/./g)


다른 두 가지 구현은 더 길다 (전체 매트릭스 : 237 바이트, 두 개의 1 행 반복 : 187).

  • 업데이트 166 : ()호출시 생략 l.
  • 업데이트 163 : 삼항에서 return학대 do하여 제거 합니다 .


0

C, 192 바이트

#define m(x,y) (x>y?x:y)
#define r(x,y) l(s,ls-x,t,lt-y)
int l(char*s,int ls,char*t,int lt){if(!ls)return lt;if(!lt)return ls;a=r(1,1);if(s[ls]==t[ls])return a;return m(m(r(0,1),r(1,0)),a)+1;}
---------

상세한

#include <stdio.h>

#define m(x,y) (x>y?x:y)
#define f(x) char x[128];fgets(x,100,stdin)
#define r(x,y) l(s,ls-x,t,lt-y)

int l(char*s,int ls,char*t,int lt)
{
    if(!ls) return lt;
    if(!lt) return ls;

    int a = r(1,1);
    if(s[ls]==t[ls]) return a;

    return m(m(r(0,1),r(1,0)),a)+1;
}

int main(void)
{
    f(a);
    f(b);
    printf("%d", l(a,strlen(a),b,strlen(b)));
    return 0;
}

0

C #을 215 210 198

public int L(string s,string t){int c,f,a,i,j;var v=new int[100];for(c=i=0;i<s.Length;i++)for(f=c=i,j=0;j<t.Length;j++){a=c;c=f;f=i==0?j+1:v[j];if(f<a)a=f;v[j]=c=s[i]==t[j]?c:1+(c<a?c:a);}return c;}

더 읽기 쉬운 :

public int L(string s,string t){
    int c,f,a,i,j;
    var v=new int[100];
    for(c=i=0;i<s.Length;i++)
        for(f=c=i,j=0;j<t.Length;j++){
            a=c;
            c=f;
            f=(i==0)?j+1:v[j];
            if (f<a) a=f;
            v[j]=c=(s[i]==t[j])?c:1+((c<a)?c:a);
        }
    return c;
}

0

PowerShell v3 +, 247 바이트

$c,$d=$args;$e,$f=$c,$d|% le*;$m=[object[,]]::new($f+1,$e+1);0..$e|%{$m[0,$_]=$_};0..$f|%{$m[$_,0]=$_};1..$e|%{$i=$_;1..$f|%{$m[$_,$i]=(($m[($_-1),$i]+1),($m[$_,($i-1)]+1),($m[($_-1),($i-1)]+((1,0)[($c[($i-1)]-eq$d[($_-1)])]))|sort)[0]}};$m[$f,$e]

나는 LD와 관련된 또 다른 문제를 해결하기 위해 이것을 만들었습니다.

주석이있는 코드 설명.

# Get both of the string passed as arguments. $c being the compare string
# and $d being the difference string. 
$c,$d=$args

# Save the lengths of these strings. $e is the length of $c and $f is the length of $d
$e,$f=$c,$d|% le*

# Create the multidimentional array $m for recording LD calculations
$m=[object[,]]::new($f+1,$e+1)

# Populate the first column 
0..$e|%{$m[0,$_]=$_}

# Populate the first row
0..$f|%{$m[$_,0]=$_}

# Calculate the Levenshtein distance by working through each position in the matrix. 
# Working the columns
1..$e|%{
    # Save the column index for use in the next pipeline
    $i=$_

    # Working the rows.
    1..$f|%{
        # Calculate the smallest value between the following values in the matrix relative to this one
        # cell above, cell to the left, cell in the upper left. 
        # Upper left also contain the cost calculation for this pass.    
        $m[$_,$i]=(($m[($_-1),$i]+1),($m[$_,($i-1)]+1),($m[($_-1),($i-1)]+((1,0)[($c[($i-1)]-eq$d[($_-1)])]))|sort)[0]
    }
}
# Return the last element of the matrix to get LD 
$m[$f,$e]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.