<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wx="http://ilps.science.uva.nl/WikiXML/wx" xml:lang="pt" lang="pt">
<head>
<title>Distância Levenshtein</title>
<meta name="wx_namespace" content="0"/>
<meta name="wx_pagename" content="Distância_Levenshtein"/>
<meta name="wx_page_id" content="148405"/>
</head>
<body>
<div id="wx_article">
<wx:section level="1" title="Distância Levenshtein" id="wxsec1"><h1 class="pagetitle" id="wx1">Distância Levenshtein</h1>

<p id="wx2">Em <a href="/wpt/Teoria_da_informa%C3%A7%C3%A3o" title="Teoria da informação" wx:linktype="known" wx:pagename="Teoria_da_informação" wx:page_id="1787" id="wx3">teoria da informação</a>, a <b id="wx4">distância Levenshtein</b> ou <b id="wx5">distância de edição</b> entre dois "strings" (duas sequências de caracteres) é dada pelo número mínimo de operações necessárias para transformar um string no outro. Entendemos por "operações" a inserção, deleção ou substituição de um carácter. O nome advém do cientista <a href="/wpt/R%C3%BAssia" title="Rússia" wx:linktype="known" wx:pagename="Rússia" wx:page_id="1669" id="wx6">russo</a> <a href="/wpt/Vladimir_Levenshtein" title="Vladimir Levenshtein" wx:linktype="known" wx:pagename="Vladimir_Levenshtein" wx:page_id="148424" id="wx7">Vladimir Levenshtein</a>, que considerou esta distância já em 1965. É muito útil para aplicações que precisam determinar quão semelhantes dois strings são, como é por exemplo o caso com os <a href="/wpt/Verificadores_ortogr%C3%A1fico" class="new" title="Verificadores ortográfico" wx:linktype="unknown" wx:pagename="Verificadores_ortográfico" id="wx8">verificadores ortográficos</a>.</p>

<div id="wx_toc"/>

<a id="Exemplo" name="Exemplo"/>
<wx:section level="2" title="Exemplo" id="wxsec2"><h2 id="wx9">Exemplo</h2>

<p id="wx10">Por exemplo, a distância Levenshtein entre as palavras inglesas "kitten" (gato) e "sitting" (sentando-se) é 3, já que com apenas 3 edições conseguimos transformar uma palavra na outra, e não há maneira de o fazer com menos de três edições:</p>

<p id="wx11"><br id="wx12"/>
</p>

<ol id="wx13">
<li id="wx14">
<p id="wx15">kitten</p>
</li>

<li id="wx16">
<p id="wx17">sitten (substituição de 'k' por 's')</p>
</li>

<li id="wx18">
<p id="wx19">sittin (substituição de 'e' por 'i')</p>
</li>

<li id="wx20">
<p id="wx21">sitting (inserção de 'g' no final)</p>
</li>
</ol>

<p id="wx22">A distância de Levenshtein pode ser considerada como uma generalização da <a href="/wpt/Dist%C3%A2ncia_Hamming" class="new" title="Distância Hamming" wx:linktype="unknown" wx:pagename="Distância_Hamming" id="wx23">Distância Hamming</a>, usada para strings com o mesmo tamanho, a qual só considera edições por substituição. Há também outras generalizações da distância Levenshtein que consideram, por exemplo, a troca de dois caracteres como uma aplicação.</p>

<a id="O_algoritmo" name="O_algoritmo"/>
</wx:section><wx:section level="2" title="O algoritmo" id="wxsec3"><h2 id="wx24">O algoritmo</h2>

<p id="wx25">Um <a href="/wpt/Algoritmo" title="Algoritmo" wx:linktype="known" wx:pagename="Algoritmo" wx:page_id="257" id="wx26">algoritmo</a> bottom-up de <a href="/wpt/Programa%C3%A7%C3%A3o_din%C3%A2mica" title="Programação dinâmica" wx:linktype="known" wx:pagename="Programação_dinâmica" wx:page_id="130662" id="wx27">programação dinâmica</a> usado frequentemente para calcular a distância Levenshtein usa uma <a href="/wpt/Matriz" title="Matriz" wx:linktype="known" wx:pagename="Matriz" wx:page_id="6745" id="wx28">matriz</a> (<var id="wx29">n</var> + 1) × (<var id="wx30">m</var> + 1), na qual <var id="wx31">n</var> e <var id="wx32">m</var> são o número de caracteres dos dois strings. Aqui um <a href="/wpt/Pseudoc%C3%B3digo" title="Pseudocódigo" wx:linktype="known" wx:pagename="Pseudocódigo" wx:page_id="71781" id="wx33">pseudocódigo</a> para uma função <i id="wx34">LevenshteinDistance</i> que usa dois strings, <i id="wx35">str1</i> de comprimento <i id="wx36">lenStr1</i>, e <i id="wx37">str2</i> de comprimento <i id="wx38">lenStr2</i>, e calcula a distância Levenshtein entre eles:</p>

<pre id="wx39">
<b id="wx40">int</b> LevenshteinDistance(<b id="wx41">char</b> str1[1..lenStr1], <b id="wx42">char</b> str2[1..lenStr2])
   <i id="wx43">// d is a table with lenStr1+1 rows and lenStr2+1 columns</i>
   <b id="wx44">declare</b> <b id="wx45">int</b> d[0..lenStr1, 0..lenStr2]
   <i id="wx46">// i and j are used to iterate over str1 and str2</i>
   <b id="wx47">declare</b> <b id="wx48">int</b> i, j, cost
 
   <b id="wx49">for</b> i <b id="wx50">from</b> 0 <b id="wx51">to</b> lenStr1
       d[i, 0] := i
   <b id="wx52">for</b> j <b id="wx53">from</b> 0 <b id="wx54">to</b> lenStr2
       d[0, j] := j
 
   <b id="wx55">for</b> i <b id="wx56">from</b> 1 <b id="wx57">to</b> lenStr1
       <b id="wx58">for</b> j <b id="wx59">from</b> 1 <b id="wx60">to</b> lenStr2
           <b id="wx61">if</b> str1[i] = str2[j] <b id="wx62">then</b> cost := 0
                                <b id="wx63">else</b> cost := 1
           d[i, j] := minimum(
                                d[i-1, j  ] + 1,     <i id="wx64">// deletion</i>
                                d[i  , j-1] + 1,     <i id="wx65">// insertion</i>
                                d[i-1, j-1] + cost   <i id="wx66">// substitution</i>
                            )
 
   <b id="wx67">return</b> d[lenStr1, lenStr2]
</pre>

<p id="wx68">A constante mantida ao longo do algoritmo é que podemos transformar o segmento inicial <code id="wx69">str1[1..i]</code> em <code id="wx70">str2[1..j]</code> usando um mínimo de operações <code id="wx71">d[i,j]</code>. No final, o elemento no fundo ao lado direito do array contém a resposta.</p>

<a id="Melhoramentos_poss.C3.ADveis" name="Melhoramentos_poss.C3.ADveis"/>
<wx:section level="3" title="Melhoramentos possíveis" id="wxsec6"><h3 id="wx72">Melhoramentos possíveis</h3>

<p id="wx73">Melhoramentos possíveis para este algoritmo poderiam ser por exemplo:</p>

<ul id="wx74">
<li id="wx75">
<p id="wx76">Podemos adaptar o algoritmo para usar menos espaço, <a href="/wpt/Big_O_notation" title="Big O notation" wx:linktype="known" wx:pagename="Big_O_notation" wx:page_id="448191" id="wx77">O</a>(m) em vez de O(mn), já que ele apenas requer que a linha anterior e a linha actual sejam armazenadas ao mesmo tempo.</p>
</li>

<li id="wx78">
<p id="wx79">Podemos armazenar o número de inserções, deleções e substituições separadamente, ou mesmo as posições em que elas ocorrem, que são sempre <code id="wx80">j</code>.</p>
</li>

<li id="wx81">
<p id="wx82">Podemos dar diferentes penalidades de custo à inserção, deleção e substituição.</p>
</li>

<li id="wx83">
<p id="wx84">A inicialização do <code id="wx85">d[i,0]</code> pode passar para dentro do grande loop principal exterior.</p>
</li>

<li id="wx86">
<p id="wx87">Este algoritmo paraleliza de uma forma pouco eficiente, devido a grande número de dependências de dados. No entanto, todo o <code id="wx88">custo</code> pode ser calculado em paralelo, e o algoritmo pode ser adaptado para perfazer a função <code id="wx89">mínimo</code> em fases para eleminar dependências.</p>
</li>
</ul>

<a id="Prova_de_sucesso" name="Prova_de_sucesso"/>
</wx:section><wx:section level="3" title="Prova de sucesso" id="wxsec7"><h3 id="wx90">Prova de sucesso</h3>

<p id="wx91">Como foi mencionado, a constante é que podemos transformar o segmento inicial <code id="wx92">s[1..i]</code> em <code id="wx93">t[1..j]</code> usando um mínimo de <code id="wx94">d[i,j]</code> operações. Esta constante é verdadeira já que:</p>

<ul id="wx95">
<li id="wx96">
<p id="wx97">É inicialmente verdadeira na linha e colunas 0 porque <code id="wx98">s[1..i]</code> pode ser transformado num string vazio <code id="wx99">t[1..0]</code> por simplesmente apagando todos os <code id="wx100">i</code> caracteres. Do mesmo modo, podemos transformar <code id="wx101">s[1..0]</code> em <code id="wx102">t[1..j]</code> ao simplesmente adicionando todos os caracteres <code id="wx103">j</code>.</p>
</li>

<li id="wx104">
<p id="wx105">O mínimo é tomado em três distâncias, sendo em qualquer das quais possível que:</p>

<ul id="wx106">
<li id="wx107">
<p id="wx108">Se podemos transformar <code id="wx109">s[1..i]</code> a <code id="wx110">t[1..j-1]</code> em <code id="wx111">k</code> operações, então nós podemos simplesmente adicionar <code id="wx112">t[j]</code> depois para obter <code id="wx113">t[1..j]</code> em <code id="wx114">k+1</code> operações.</p>
</li>

<li id="wx115">
<p id="wx116">Se podemos transformar <code id="wx117">s[1..i-1]</code> a <code id="wx118">t[1..j]</code> em <code id="wx119">k</code> operações, então nós podemos fazer as mesmas operações em <code id="wx120">s[1..i]</code> e depois remover o <code id="wx121">s[i]</code> original ao fim de <code id="wx122">k+1</code> operações.</p>
</li>

<li id="wx123">
<p id="wx124">Se podemos transformar <code id="wx125">s[1..i-1]</code> a <code id="wx126">t[1..j-1]</code> em <code id="wx127">k</code> operações, então podemos fazer o mesmo com <code id="wx128">s[1..i]</code> e depois fazer uma substituição de <code id="wx129">t[j]</code> pelas <code id="wx130">s[i]</code> originais no final, se necessário, requerindo <code id="wx131">k+cost</code> operações.</p>
</li>
</ul>
</li>

<li id="wx132">
<p id="wx133">As operações requiridas para transformar <code id="wx134">s[1..n]</code> em <code id="wx135">t[1..m]</code> é o número necessário para transformar todos os <code id="wx136">s</code> em todos os <code id="wx137">t</code>, e logo <code id="wx138">d[n,m]</code> contém o nosso resultado desejado.</p>
</li>
</ul>

<p id="wx139">Esta prova não confirma que o número colocado em <code id="wx140">d[i,j]</code> seja de facto o mínimo; isso é mais difícil de provar e exige um argumento Reductio ad absurdum no qual assumimos que <code id="wx141">d[i,j]</code> é mais pequeno do que o mínimo dos três, e usamos isto para mostrar que um dos três não é mínimo.</p>

<a id="Implementa.C3.A7.C3.B5es" name="Implementa.C3.A7.C3.B5es"/>
</wx:section><wx:section level="3" title="Implementações" id="wxsec8"><h3 id="wx142">Implementações</h3>

<p id="wx143">Exemplo de implementações podem ser encontrados em <a href="http://wikisource.org/wiki/Levenshtein_distance" class="external text" wx:linktype="external" rel="nofollow" id="wx144">Wikisource</a>.</p>

<a id="Limites_superior_e_inferior" name="Limites_superior_e_inferior"/>
</wx:section></wx:section><wx:section level="2" title="Limites superior e inferior" id="wxsec4"><h2 id="wx145">Limites superior e inferior</h2>

<p id="wx146">A distância Levenshtein tem vários limites superior e inferior simples que são úteis em aplicações que calculam vários deles e os comparam. Estes incluem:</p>

<ul id="wx147">
<li id="wx148">
<p id="wx149">É sempre pelo menos igual à diferença dos tamanhos dos dois strings.</p>
</li>

<li id="wx150">
<p id="wx151">É no máximo igual ao tamanho do string mais longo.</p>
</li>

<li id="wx152">
<p id="wx153">É zero se e só se os strings são idênticos.</p>
</li>

<li id="wx154">
<p id="wx155">Se os strings têm o mesmo tamanho, a <a href="/wpt/Dist%C3%A2ncia_Hamming" class="new" title="Distância Hamming" wx:linktype="unknown" wx:pagename="Distância_Hamming" id="wx156">distância Hamming</a> é um limite superior da distância Levenshtein.</p>
</li>

<li id="wx157">
<p id="wx158">Se os strings são chamados <code id="wx159">s</code> e <code id="wx160">t</code>, o número de caracteres (não contando os duplicados) que encontramos em <code id="wx161">s</code> mas não em <code id="wx162">t</code> é um limite inferior.</p>
</li>
</ul>

<a id="Links_.28em_portugu.C3.AAs.2C_ingl.C3.AAs_e_alem.C3.A3o.29" name="Links_.28em_portugu.C3.AAs.2C_ingl.C3.AAs_e_alem.C3.A3o.29"/>
</wx:section><wx:section level="2" title="Links (em português, inglês e alemão)" id="wxsec5"><h2 id="wx163">Links (em português, inglês e alemão)</h2>

<ul id="wx164">
<li id="wx165"><a href="http://www.dcc.ufmg.br/~nivio/cursos/pa03/seminarios/seminario4/seminario4.pdf" class="external text" wx:linktype="external" rel="nofollow" id="wx166">O fantástico mundo da distância de edição (um survey em formato PDF sobre distância de edição)</a></li>

<li id="wx167"><a href="http://www.merriampark.com/ld.htm" class="external text" wx:linktype="external" rel="nofollow" id="wx168">Levenshtein Distance, in Three Flavors, by Michael Gilleland</a></li>

<li id="wx169"><a href="http://www.nist.gov/dads/HTML/Levenshtein.html" class="external text" wx:linktype="external" rel="nofollow" id="wx170">NIST's Dictionary of Algorithms and Data Structures: Levenshtein Distance</a></li>

<li id="wx171"><a href="http://www.cs.washington.edu/education/courses/590bi/96wi/" class="external text" wx:linktype="external" rel="nofollow" id="wx172">CSE 590BI, Winter 1996 Algorithms in Molecular Biology</a>
<p id="wx173">The algorithms from lectures 2, 3 and 4 are based on the Levenshtein distance but implement a different scoring function. The Haskell example was based on these notes.</p>
</li>

<li id="wx174"><a href="http://www-igm.univ-mlv.fr/~lecroq/seqcomp/node2.html" class="external text" wx:linktype="external" rel="nofollow" id="wx175">Levenshtein Distance - visualized</a></li>

<li id="wx176"><a href="http://www.cut-the-knot.org/do_you_know/Strings.shtml" class="external text" wx:linktype="external" rel="nofollow" id="wx177">Distance between strings - Levenshtein and Hamming</a></li>

<li id="wx178"><a href="http://www.cs.unm.edu/~luger/ai-final/demos.html" class="external text" wx:linktype="external" rel="nofollow" id="wx179">Another Edit Distance Visualization (very fast)</a></li>

<li id="wx180"><a href="http://www.levenshtein.de/" class="external text" wx:linktype="external" rel="nofollow" id="wx181">Wie funktioniert der Levenshtein-Algorithmus...?</a></li>
</ul>
</wx:section></wx:section></div>
<div id="wx_categorylinks">
<a href="/wpt/index.php?title=Especial:Categories&amp;article=Dist%C3%A2ncia_Levenshtein" title="Especial:Categories" wx:linktype="known" wx:pagename="Especial:Categories" id="wx182">Categorias de páginas</a>: <span dir="ltr" id="wx183"><a href="/wpt/Categoria:Algoritmos" title="Categoria:Algoritmos" wx:linktype="known" wx:pagename="Categoria:Algoritmos" wx:page_id="28962" id="wx184">Algoritmos</a></span></div>
<div id="wx_languagelinks">
Outras línguas: <a href="http://af.wikipedia.org/wiki/Levenshteinafstand" class="external" wx:linktype="interwiki" wx:pagename="af:Levenshteinafstand" id="wx185">Afrikaans</a> | <a href="http://de.wikipedia.org/wiki/Levenshtein-Distanz" class="external" wx:linktype="interwiki" wx:pagename="de:Levenshtein-Distanz" id="wx186">Deutsch</a> | <a href="http://en.wikipedia.org/wiki/Levenshtein_distance" class="external" wx:linktype="interwiki" wx:pagename="en:Levenshtein_distance" id="wx187">English</a> | <a href="http://es.wikipedia.org/wiki/Distancia_de_Levenshtein" class="external" wx:linktype="interwiki" wx:pagename="es:Distancia_de_Levenshtein" id="wx188">Español</a> | <a href="http://fi.wikipedia.org/wiki/Leven%C5%A1teinin_et%C3%A4isyys" class="external" wx:linktype="interwiki" wx:pagename="fi:Levenšteinin_etäisyys" id="wx189">Suomi</a> | <a href="http://fr.wikipedia.org/wiki/Distance_de_Levenshtein" class="external" wx:linktype="interwiki" wx:pagename="fr:Distance_de_Levenshtein" id="wx190">Français</a> | <a href="http://it.wikipedia.org/wiki/Distanza_di_Levenshtein" class="external" wx:linktype="interwiki" wx:pagename="it:Distanza_di_Levenshtein" id="wx191">Italiano</a> | <a href="http://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%BC%E3%83%99%E3%83%B3%E3%82%B7%E3%83%A5%E3%82%BF%E3%82%A4%E3%83%B3%E8%B7%9D%E9%9B%A2" class="external" wx:linktype="interwiki" wx:pagename="ja:レーベンシュタイン距離" id="wx192">日本語</a> | <a href="http://lv.wikipedia.org/wiki/Leven%C5%A1teina_att%C4%81lums" class="external" wx:linktype="interwiki" wx:pagename="lv:Levenšteina_attālums" id="wx193">Latviešu</a> | <a href="http://nl.wikipedia.org/wiki/Levenshteinafstand" class="external" wx:linktype="interwiki" wx:pagename="nl:Levenshteinafstand" id="wx194">Nederlands</a> | <a href="http://nn.wikipedia.org/wiki/Levenshtein-distanse" class="external" wx:linktype="interwiki" wx:pagename="nn:Levenshtein-distanse" id="wx195">Norsk (nynorsk)</a> | <a href="http://pl.wikipedia.org/wiki/Odleg%C5%82o%C5%9B%C4%87_Levenshteina" class="external" wx:linktype="interwiki" wx:pagename="pl:Odległość_Levenshteina" id="wx196">Polski</a> | <a href="http://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD%D0%B0" class="external" wx:linktype="interwiki" wx:pagename="ru:Расстояние_Левенштейна" id="wx197">Русский</a> | <a href="http://sr.wikipedia.org/wiki/%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B0%D1%98%D0%BD%D0%BE%D0%B2%D0%BE_%D1%80%D0%B0%D1%81%D1%82%D0%BE%D1%98%D0%B0%D1%9A%D0%B5" class="external" wx:linktype="interwiki" wx:pagename="sr:Левенштајново_растојање" id="wx198">Српски / Srpski</a> | <a href="http://tg.wikipedia.org/wiki/%D0%9C%D0%B0%D1%81%D0%BE%D1%84%D0%B0%D0%B8_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD" class="external" wx:linktype="interwiki" wx:pagename="tg:Масофаи_Левенштейн" id="wx199">Тоҷикӣ</a> | <a href="http://uk.wikipedia.org/wiki/%D0%92%D1%96%D0%B4%D1%81%D1%82%D0%B0%D0%BD%D1%8C_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD%D0%B0" class="external" wx:linktype="interwiki" wx:pagename="uk:Відстань_Левенштейна" id="wx200">Українська</a> | <a href="http://zh.wikipedia.org/wiki/%E7%B7%A8%E8%BC%AF%E8%B7%9D%E9%9B%A2" class="external" wx:linktype="interwiki" wx:pagename="zh:編輯距離" id="wx201">中文</a></div>
</body>
</html>
