1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
<?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
-->
|