php-doc-en/reference/strings/functions/levenshtein.xml
2004-12-03 16:01:33 +00:00

207 lines
6.4 KiB
XML

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision: 1.7 $ -->
<!-- splitted from ./en/functions/strings.xml, last change in rev 1.12 -->
<refentry id="function.levenshtein">
<refnamediv>
<refname>levenshtein</refname>
<refpurpose>
Calculate Levenshtein distance between two strings
</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>int</type><methodname>levenshtein</methodname>
<methodparam><type>string</type><parameter>str1</parameter></methodparam>
<methodparam><type>string</type><parameter>str2</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>cost_ins</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>cost_rep</parameter></methodparam>
<methodparam><type>int</type><parameter>cost_del</parameter></methodparam>
</methodsynopsis>
<!-- Callback function not yet implemented, see bug #29552
<methodsynopsis>
<type>int</type><methodname>levenshtein</methodname>
<methodparam><type>string</type><parameter>str1</parameter></methodparam>
<methodparam><type>string</type><parameter>str2</parameter></methodparam>
<methodparam><type>callback</type><parameter>cost</parameter></methodparam>
</methodsynopsis>
-->
<para>
This function returns the Levenshtein-Distance between the
two argument strings or -1, if one of the argument strings
is longer than the limit of 255 characters.
</para>
<para>
The Levenshtein distance is defined as the minimal number of
characters you have to replace, insert or delete to transform
<parameter>str1</parameter> into <parameter>str2</parameter>.
The complexity of the algorithm is <literal>O(m*n)</literal>,
where <literal>n</literal> and <literal>m</literal> are the
length of <parameter>str1</parameter> and
<parameter>str2</parameter> (rather good when compared to
<function>similar_text</function>, which is O(max(n,m)**3),
but still expensive).
</para>
<para>
In its simplest form the function will take only the two
strings as parameter and will calculate just the number of
insert, replace and delete operations needed to transform
<parameter>str1</parameter> into <parameter>str2</parameter>.
</para>
<para>
A second variant will take three additional parameters that
define the cost of insert, replace and delete operations. This
is more general and adaptive than variant one, but not as
efficient.
</para>
<!-- Callback function not yet implemented, see bug #29552
<para>
The third variant (which is not implemented yet) will be the most
general and adaptive, but also the slowest alternative. It will
call a user-supplied function that will determine the cost for
every possible operation.
</para>
<para>
The user-supplied function will be called with the following
arguments:
<itemizedlist>
<listitem>
<simpara>
operation to apply: 'I', 'R' or 'D'
</simpara>
</listitem>
<listitem>
<simpara>
actual character in string 1
</simpara>
</listitem>
<listitem>
<simpara>
actual character in string 2
</simpara>
</listitem>
<listitem>
<simpara>
position in string 1
</simpara>
</listitem>
<listitem>
<simpara>
position in string 2
</simpara>
</listitem>
<listitem>
<simpara>
remaining characters in string 1
</simpara>
</listitem>
<listitem>
<simpara>
remaining characters in string 2
</simpara>
</listitem>
</itemizedlist>
The user-supplied function has to return a positive integer
describing the cost for this particular operation, but it may
decide to use only some of the supplied arguments.
</para>
<para>
The user-supplied function approach offers the possibility to
take into account the relevance of and/or difference between
certain symbols (characters) or even the context those symbols
appear in to determine the cost of insert, replace and delete
operations, but at the cost of losing all optimizations done
regarding cpu register utilization and cache misses that have
been worked into the other two variants.
</para>
-->
<para>
<example>
<title><function>levenshtein</function> example</title>
<programlisting role="php">
<![CDATA[
<?php
// input misspelled word
$input = 'carrrot';
// array of words to check against
$words = array('apple','pineapple','banana','orange',
'radish','carrot','pea','bean','potato');
// no shortest distance found, yet
$shortest = -1;
// loop through words to find the closest
foreach ($words as $word) {
// calculate the distance between the input word,
// and the current word
$lev = levenshtein($input, $word);
// check for an exact match
if ($lev == 0) {
// closest word is this one (exact match)
$closest = $word;
$shortest = 0;
// break out of the loop; we've found an exact match
break;
}
// if this distance is less than the next found shortest
// distance, OR if a next shortest word has not yet been found
if ($lev <= $shortest || $shortest < 0) {
// set the closest match, and shortest distance
$closest = $word;
$shortest = $lev;
}
}
echo "Input word: $input\n";
if ($shortest == 0) {
echo "Exact match found: $closest\n";
} else {
echo "Did you mean: $closest?\n";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Input word: carrrot
Did you mean: carrot?
]]>
</screen>
</example>
</para>
<para>
See also <function>soundex</function>,
<function>similar_text</function>, and
<function>metaphone</function>.
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->