﻿<h1 class=p1>Функции сравнения строк</h1>
<table border="0" cellspacing="10">
    <tr valign="top">
        <td>
            <a class=bluelink href="#1" title="Функция сравнения строк">strcmp()</a>&nbsp;<br>
            <a class=bluelink href="#2" title="Функция сравнения начала строк">strncmp()</a>&nbsp;<br>
        </td>
        <td>
            <a class=bluelink href="#3" title="Функция сравнения строк без учета регистра">strcasecmp()</a>&nbsp;<br>       
            <a class=bluelink href="#4" title="Функция cравнения начала строк без учета регистра">strncasecmp()</a>&nbsp;<br>       
        </td>
        <td>
            <a class=bluelink href="#5" title='Производит так называемое "естественное" сравнение строк'>strnatcmp()</a>&nbsp;<br>
            <a class=bluelink href="#6" title='Производит "естественное" сравнение строк без учета регистра'>strnatcasecmp()</a>&nbsp;<br>
        </td>
        <td>    
            <a class=bluelink href="#7" title="Функция определения схожести двух строк">similar_text()</a>&nbsp;<br>        
            <a class=bluelink href="#8" title="Функция выполняет определение различия Левенштейна двух строк">levenshtein()</a>&nbsp;<br>                   
        </td>
    </tr>
</table>
<br>

<a name=1></a>
<h1 class=p1>strcmp()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
int <b>strcmp</b><em class=gr>(</em>string <b>str1</b>, string <b>str2</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Эта функция сравнения строк. Она сравнивает две строки  и возвращает:</p>
<ul>
  <li>0 - если строки полностью совпадают;</li>
  <li>1 - если, строка <b>str1</b> лексикографически больше <b>str2</b>;</li>
  <li>1 – если, наоборот, строка <b>str1</b> лексикографически меньше <b>str2</b></li>
</ul>
<p class=text>Функция является чувствительной к регистру, т.е. регистр символов влияет на результаты сравнений (поскольку сравнение происходит побайтово).</p>
<p class=prim><b><i>Пример:</i></b></p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$str1</b> <em class=gr>=</em> "ttt"<em class=gr>;</em>
   <b>$str2</b> <em class=gr>=</em> "tttttttttt"<em class=gr>;</em>
   <em class=gr>echo(</em>"Result of strcmp (<b>$str1</b> , <b>$str2</b>) is ");
   <em class=gr>echo(</em>strcmp <em class=gr>(</em><b>str1</b>, <b>str2</b><em class=gr>)); echo(</em>"&lt;<b>br</b>>"<em class=gr>);</em>
   <em class=gr>echo(</em>"Result of strcmp (<b>$str2</b>, <b>$str1</b>)> is ");
   <em class=gr>echo(</em>strcmp <em class=gr>(</em><b>str2</b>, <b>str1</b><em class=gr>)); echo(</em>"&lt;<b>br</b>>"<em class=gr>);</em>
   <em class=gr>echo(</em>"Result of strcmp ($str1 , $str1) is ");
   <em class=gr>echo(</em>strcmp (<b>str1</b>,<b>str1</b><em class=gr>));</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=prim><b><i>Результат:</i></b></p>
<table border="0" summary="">
    <tr>
        <td colspan="2"><img src="images/gl3_2.gif" tppabs="http://site/bookphp/images/gl3_2.gif" border="0" width="399" height="90" alt=""></td>
    </tr>
    <tr><td width="20">&nbsp;</td>
        <td><p class=html>
            Result of strcmp (ttt , tttttttttt) is -1<br>
            Result of strcmp (tttttttttt, ttt) is 1<br>         
            Result of strcmp (ttt, ttt) is 0            
        </td>
    </tr>
</table>
<br>

<a name=2></a>
<h1 class=p1>strncmp()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
int <b>strncmp</b><em class=gr>(</em>string <b>str1</b>, string <b>str2</b>, int <b>len</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Эта функция отличается от <b>strcmp</b>() тем, что сравнивает начала строк, а точнее первые <b>len</b> байтов. Если <b>len</b> меньше длины наименьшей из строк, то строки сравниваются целиком.</p>
<p class=text>В остальном функция ведет себя аналогично  <b>strcmp</b>(), т.е. возвращает:</p>
<ul>
  <li>0 - если строки полностью совпадают;</li>
  <li>1 - если, строка <b>str1</b> лексикографически больше <b>str2</b>;</li>
  <li>1 – если, наоборот, строка <b>str1</b> лексикографически меньше <b>str2</b> </li>
</ul>
<p class=text>Сравнение также проводится побайтово, поэтому функция чувствительна к регистру.</p>
<br>

<a name=3></a>
<h1 class=p1>strcasecmp()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
int <b>strcasecmp</b><em class=gr>(</em>string <b>str1</b>, string <b>str2</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Функция работает аналогично <b>strcmp</b>(), только при работе не учитывается регистр букв.</p>
<br>

<a name=4></a>
<h1 class=p1>strncasecmp()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
int <b>strncasecmp</b><em class=gr>(</em>string <b>str1</b>, string <b>str2</b>, int <b>len</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Функция <b>strncasecmp</b>() cравнивает начала строк без учета регистра.</p>
<br>

<a name=5></a>
<h1 class=p1>strnatcmp()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
int <b>strnatcmp</b><em class=gr>(</em>string <b>str1</b>, string <b>str2</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Производит так называемое "естественное" сравнение строк.</p>

<p class=text>Об этой функции поговорим поподробнее. Данная функция является имитатором сравнение строк человеком, т.е. она сравнивает строки так, как их сравнивал бы человек. Т.е., если, к примеру, мы будем сравнивать файлы с названиями pict1.gif, pict20.gif, pict2.gif, pict10.gif, то обычное сравнение приведет к следующему их расположению: pict1.gif, pict10.gif, pict2.gif, pict20.gif. Естественная же сортировка даст результат, который нам более привычен: pict1.gif, pict2.gif, pict10.gif, pict20.gif.</p>
<p class=text>В примере использования этой функции мы опять забежим вперед и прибегнем к функциям работы с массивами. Поэтому мы советуем Вам после прочтения главы о массивах еще раз взглянуть на этот пример, и использовать его, когда Вам надо отсортировать все то, что связано со строками, к примеру, названия файлов.</p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$array1</b> = <b>$array2</b> = array("pict10.gif", "pict2.gif", "pict20.gif", "pict1.gif");
   <em class=gr>echo(</em>"обычная сортировка:"<em class=gr>); echo (</em>"&lt;<b>br</b>>"<em class=gr>);</em>
   usort <em class=gr>(</em><b>$array1</b>, strcmp<em class=gr>);</em>
   print_r <em class=gr>(</em>$array1<em class=gr>);</em>
   echo <em class=gr>(</em>"&lt;<b>br</b>>"<em class=gr>); echo(</em>"естественная сортировка:"<em class=gr>); echo(</em>"&lt;<b>br</b>>"<em class=gr>);</em>
   usort <em class=gr>(</em><b>$array2</b>, strnatcmp<em class=gr>);</em>
   print_r <em class=gr>(</em><b>$array2</b><em class=gr>);</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Этот скрипт выведет следующее:</p>
<table border="0" summary="">
    <tr>
        <td colspan="2"><img src="images/gl3_2.gif" tppabs="http://site/bookphp/images/gl3_2.gif" border="0" width="399" height="90" alt=""></td>
    </tr>
    <tr><td width="20">&nbsp;</td>
        <td><p class=html>
            обычная сортировка:<br>
            Array([0]=>pict1.gif [1]=> pict10.gif [2]=>pict2.gif [3]pict20.gif)<br>
            естественная сортировка:<br>
            Array([0]=>pict1.gif [1]=> pict2.gif [2]=>pict10.gif [3]pict20.gif)         
        </td>
    </tr>
</table>

<br>
 
<a name=6></a>
<h1 class=p1>strnatcasecmp()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
int <b>strnatcasecmp</b><em class=gr>(</em>string <b>str1</b>, string <b>str2</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Производит "естественное" сравнение строк без учета регистра. Функция выполняет то же самое, что и <b>strnatcmp</b>(), только без учета регистра. </p>
<br>


<a name=7></a>
<h1 class=p1>similar_text()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
int <b>similar_text</b><em class=gr>(</em>string <b>str_first</b>, string <b>str_second</b> [, double <b>percent</b>]<em class=gr>)</em>
</pre></blockquote>
<p class=text>Эта функция производит определение схожести двух строк.</p>
<p class=text>Функция <b>similar_text</b>() определяет схожесть двух строк по алгоритму Оливера. Функция возвращает число символов, совпавших в строках <b>str_first</b> и <b>str_second</b>. Третий необязательный параметр передается по ссылке и в нем сохраняется процент совпадения строк.</p> 
<blockquote class=citat>Вместо стека, как в алгоритме Оливера, эта функция использует рекурсивные вызовы. Сложность алгоритма этой функции равна <b>O((max(n,m))3)</b>, что делает эту функцию медленной. (Грубо говоря, скорость выполнения этой функции пропорциональна <b>N3</b>, где <b>N</b> – длина наибольшей строки.</p>
</blockquote>
<p class=prim><b><i>Пример:</i></b></p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$str1</b> <em class=gr>=</em> "Hello, world!"<em class=gr>;</em>
   <b>$str2</b> <em class=gr>=</em> "Hello!"<em class=gr>;</em>
   <b>$var</b> <em class=gr>=</em> similar_text<em class=gr>(</em><b>$str1</b>,<b>$str2</b><em class=gr>);</em>
   <b>$var1</b> <em class=gr>=</em> similar_text<em class=gr>(</em><b>$str1</b>, <b>$str2</b>, &<b>$tmp</b><em class=gr>);</em>
   // <em class=comnt>параметр $tmp передаем по ссылке</em>
   <em class=gr>echo(</em>"Результат выполнения функции similar_text()
   для строк $str и $str1 в количестве символов:"<em class=gr>);</em>
   <em class=gr>echo(</em>"&lt;<b>br</b>>"<em class=gr>);</em> <em class=gr>echo(</em>"$var"); <em class=gr>echo(</em>"&lt;<b>br</b>>"<em class=gr>);</em>
   <em class=gr>echo(</em>"и в процентах:"<em class=gr>);</em> <em class=gr>echo(</em>"&lt;<b>br</b>>"<em class=gr>);</em>
   <em class=gr>echo(</em><b>$tmp</b><em class=gr>);</em> // <em class=comnt>для вывода информации в процентах обращаемся к <b>$tmp</b></em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=prim><b><i>Результат:</i></b></p>
<table border="0" summary="">
    <tr>
        <td colspan="2"><img src="images/gl3_2.gif" tppabs="http://site/bookphp/images/gl3_2.gif" border="0" width="399" height="90" alt=""></td>
    </tr>
    <tr><td width="20">&nbsp;</td>
        <td><p class=html>
            Результат выполнения функции similar_text() для строк Hello, world! и Hello! в количестве символов:<br>
            6<br>
            и в процентах:<br>
            63.157894736842 
        </td>
    </tr>
</table>
<br>

<a name=8></a>
<h1 class=p1>levenshtein()</h1>
<p class=text>Функция выполняет определение различия Левенштейна двух строк.</p>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
int <b>levenshtein</b><em class=gr>(</em>string <b>str1</b>, string <b>str2</b><em class=gr>)</em>
int <b>levenshtein</b><em class=gr>(</em>string <b>str1</b>, string <b>str2</b>, int <b>cost_ins</b>, int <b>cost_rep</b>, int <b>cost_del</b><em class=gr>)</em>
int <b>levenshtein</b><em class=gr>(</em>string <b>str1</b>, string <b>str2</b>, function <b>cost</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Под понятием "<i>различие&nbsp;Левенштейна</i>" понимается минимальное число символов, которое требовалось бы заменить, вставить или удалить для того, чтобы превратить строку <b>str1</b> в <b>str2</b>. </p>
<p class=text>Сложность алгоритма этой функции равна <b>O(m*n)</b>, т.е. пропорциональна произведению длин строк <b>str1</b> и <b>str2</b>, поэтому эта функция намного более быстрая, чем функция <b>similar_text</b>(). 
<p class=text>Как видим, у функции три вида синтаксиса. В первом случае функция возвращает число необходимых операций над символами строк для преобразования <b>str1</b> в <b>str2:</b>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$str1</b> <em class=gr>=</em> "Hello, world!"<em class=gr>;</em>
   <b>$str2</b> <em class=gr>=</em> "Hello!"<em class=gr>;</em>
   <b>$var</b> <em class=gr>=</em> levenshtein<em class=gr>(</em><b>$str1</b>,<b>$str2</b><em class=gr>);</em>
   <em class=gr>echo(</em><b>$var</b><em class=gr>);</em> // <em class=comnt>вернет 7</em>
<em class=red>?&gt;</em>
</pre></blockquote>

<p class=text>Во втором случае добавляется три дополнительных параметра: стоимость операции вставки <b>cost_ins</b>, замены <b>cost_rep</b> и удаления <b>cost_del</b>. Естественно, функция в этом случае становится менее быстродействующей. Возвращается интегральный показатель сложности трансформации (ИПСТ).</p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$str1</b> <em class=gr>=</em> "Hello, world!"<em class=gr>;</em>
   <b>$str2</b> <em class=gr>=</em> "Hello!"<em class=gr>;</em>
   <b>$var</b> <em class=gr>=</em> levenshtein<em class=gr>(</em><b>$str1</b>,<b>$str2</b>,3,3,3<em class=gr>);</em>
   <em class=gr>echo(</em><b>$var</b><em class=gr>);</em> // <em class=comnt>вернет 21</em>
<em class=red>?&gt;</em>
</pre></blockquote>

<p class=text>Число 21, между прочим, это 7*3 :). Т.е. ИПСТ равен произведению количества символов, необходимых для замены (а как мы посчитали в предыдущем примере их надобно 7) на стоимость, в этом случае, одной из операций. В этом примере, поскольку стоимость одинакова, не имеет значения, какую операцию брать. В случае, если стоимости различны, при вычисления ИПСТ берется наибольший. Т.е., если мы напишем в этом примере   
<blockquote><pre>
<b>$var</b> <em class=gr>=</em> levenshtein<em class=gr>(</em><b>$str1</b>, <b>str2</b> ,2,3,6<em class=gr>);</em>
</pre></blockquote>
<p class=text>то функция вернет нам значение 42.</p>
<p class=text>Третий вариант позволяет указать функцию, используемую для расчета сложности трансформации. </p>