<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Complexity This algorithm &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/complexity-this-algorithm/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>on web development</description>
	<lastBuildDate>Tue, 13 Feb 2018 08:18:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.3</generator>
	<item>
		<title>Computer Algorithms: Morris-Pratt String Searching</title>
		<link>/2012/04/09/computer-algorithms-morris-pratt-string-searching/</link>
		<comments>/2012/04/09/computer-algorithms-morris-pratt-string-searching/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 19:41:05 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Applied mathematics]]></category>
		<category><![CDATA[Boyer–Moore string search algorithm]]></category>
		<category><![CDATA[Brute-force search]]></category>
		<category><![CDATA[Complexity This algorithm]]></category>
		<category><![CDATA[Computer programming]]></category>
		<category><![CDATA[Computer science]]></category>
		<category><![CDATA[faster string searching algorithms]]></category>
		<category><![CDATA[James H. Morris]]></category>
		<category><![CDATA[Knuth–Morris–Pratt algorithm]]></category>
		<category><![CDATA[Lorem ipsum]]></category>
		<category><![CDATA[Morris-Pratt algorithm]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Rabin]]></category>
		<category><![CDATA[Rabin-Karp algorithm]]></category>
		<category><![CDATA[Rabin-Karp string search algorithm]]></category>
		<category><![CDATA[search algorithms]]></category>
		<category><![CDATA[String searching algorithm]]></category>
		<category><![CDATA[Vaughan Pratt]]></category>

		<guid isPermaLink="false">/?p=3019</guid>
		<description><![CDATA[Introduction We saw that neither brute force string searching nor Rabin-Karp string searching are effective. However in order to improve some algorithm, first we need to understand its principles in detail. We know already that brute force string matching is slow and we tried to improve it somehow by using a hash function in the &#8230; <a href="/2012/04/09/computer-algorithms-morris-pratt-string-searching/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Morris-Pratt String Searching</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/04/17/computer-algorithms-boyer-moore-string-search-and-matching/" rel="bookmark" title="Computer Algorithms: Boyer-Moore String Searching">Computer Algorithms: Boyer-Moore String Searching </a></li>
<li><a href="/2012/04/02/computer-algorithms-rabin-karp-string-searching/" rel="bookmark" title="Computer Algorithms: Rabin-Karp String Searching">Computer Algorithms: Rabin-Karp String Searching </a></li>
<li><a href="/2012/03/27/computer-algorithms-brute-force-string-matching/" rel="bookmark" title="Computer Algorithms: Brute Force String Matching">Computer Algorithms: Brute Force String Matching </a></li>
<li><a href="/2011/08/18/powerful-php-less-known-string-manipulation/" rel="bookmark" title="Powerful PHP: Less Known String Manipulation">Powerful PHP: Less Known String Manipulation </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>We saw that neither <a href="/2012/03/27/computer-algorithms-brute-force-string-matching/" title="Computer Algorithms: Brute Force String Matching">brute force string searching</a> nor <a href="/2012/04/02/computer-algorithms-rabin-karp-string-searching/" title="Computer Algorithms: Rabin-Karp String Searching">Rabin-Karp string searching</a> are effective. However in order to improve some algorithm, first we need to understand its principles in detail. We know already that brute force string matching is slow and we tried to improve it somehow by using a hash function in the Rabin-Karp algorithm. The problem is that Rabin-Karp has the same complexity as brute force string matching, which is O(mn).</p>
<p>Obviously we need a different approach, but to come with a different approach let’s see what’s wrong with brute force string searching. Indeed by taking a closer look at its principles we can answer the question. </p>
<p>In brute force matching we checked each character of the text with the first character of the pattern. In case of a match we shifted the comparison between the second character of the pattern and the next character of the text. The problem is that in case of a mismatch we must go several positions back in the text. Well in fact this technique can’t be optimized. </p>
<p><figure id="attachment_3025" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Morris-Pratt-brute-force-string-matching.png"><img src="/wp-content/uploads/2012/04/Morris-Pratt-brute-force-string-matching.png" alt="Morris-Pratt brute force string matching" title="Morris-Pratt brute force string matching" width="620" height="360" class="size-full wp-image-3025" srcset="/wp-content/uploads/2012/04/Morris-Pratt-brute-force-string-matching.png 620w, /wp-content/uploads/2012/04/Morris-Pratt-brute-force-string-matching-300x174.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">In brute force string matching in case of a mismatch we go back and we compare characters that has been compared already!</figcaption></figure><span id="more-3019"></span></p>
<p>As you can see on the picture above the problem is that once there is a mismatch we must rollback and start comparing from a position in the text that has been explored already. In our case we have checked the first, second, third and fourth letters, where there is a mismatch between the pattern and the text and then &#8230; we go back and start comparing from the second letter of the text.</p>
<p>This is completely useless, because we already know that the pattern begins with the letter “a” and no such letter happens to be between positions 1 and 3. So how can we improve this redundancy?</p>
<h2>Overview</h2>
<p>The answer of the question came to <a href="http://en.wikipedia.org/wiki/James_H._Morris" title="James H. Morris" target="_blank">James H. Morris</a> and <a href="http://en.wikipedia.org/wiki/Vaughan_Pratt" title="Vaughan Pratt" target="_blank">Vaughan Pratt</a> in 1977 when they described their algorithm, which by skipping lots of useless comparisons is more effective than brute force string matching. Let’s see it in detail. The only thing is to use the information gathered during the comparisons of the pattern and a possible match, as on the picture below.</p>
<figure id="attachment_3029" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Morris-Pratt-basic-principles.png"><img src="/wp-content/uploads/2012/04/Morris-Pratt-basic-principles.png" alt="Morris-Pratt basic principles" title="Morris-Pratt basic principles" width="620" height="483" class="size-full wp-image-3029" srcset="/wp-content/uploads/2012/04/Morris-Pratt-basic-principles.png 620w, /wp-content/uploads/2012/04/Morris-Pratt-basic-principles-300x233.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">Morris-Pratt skips some comparisons by moving ahead to the next possible position of a match!</figcaption></figure>
<p>To do that first we have to preprocess the pattern in order to get possible positions for next matches. Thus after we start to find a possible match in case of a mismatch we’ll know exactly where we should jump in order to skip unusual comparisons.</p>
<h3>Generating the Table of Next Positions</h3>
<p>This is the tricky part in Morris-Pratt and that is how this algorithm overcomes the disadvantages of brute force string searching. Let&#8217;s see some pictures.</p>
<figure id="attachment_3044" style="width: 623px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Morris-Pratt-with-no-repeating-letters-in-the-pattern.png"><img src="/wp-content/uploads/2012/04/Morris-Pratt-with-no-repeating-letters-in-the-pattern.png" alt="Morris-Pratt with no repeating letters in the pattern" title="Morris-Pratt with no repeating letters in the pattern" width="623" height="361" class="size-full wp-image-3044" srcset="/wp-content/uploads/2012/04/Morris-Pratt-with-no-repeating-letters-in-the-pattern.png 623w, /wp-content/uploads/2012/04/Morris-Pratt-with-no-repeating-letters-in-the-pattern-300x173.png 300w" sizes="(max-width: 623px) 100vw, 623px" /></a><figcaption class="wp-caption-text">It is clear that if the pattern consists only of different letters in case of a mismatch we should start comparing the next character of the text with the first character of the pattern!</figcaption></figure>
<p>However in case of repeating character in the pattern if we have a mismatch after that character a possible match must begin from this repeating character, as on the picture bellow.</p>
<figure id="attachment_3045" style="width: 622px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Morris-Pratt-with-one-repeating-letter-in-the-pattern.png"><img src="/wp-content/uploads/2012/04/Morris-Pratt-with-one-repeating-letter-in-the-pattern.png" alt="Morris-Pratt with one repeating letter in the pattern" title="Morris-Pratt with one repeating letter in the pattern" width="622" height="404" class="size-full wp-image-3045" srcset="/wp-content/uploads/2012/04/Morris-Pratt-with-one-repeating-letter-in-the-pattern.png 622w, /wp-content/uploads/2012/04/Morris-Pratt-with-one-repeating-letter-in-the-pattern-300x194.png 300w" sizes="(max-width: 622px) 100vw, 622px" /></a><figcaption class="wp-caption-text">The next table is slightly different if the pattern has repeating character! </figcaption></figure>
<p>Finally if there are more than one repeating character in the text the &#8220;next&#8221; table will consist show their position.</p>
<figure id="attachment_3046" style="width: 622px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Morris-Pratt-more-than-one-repeating-letter-in-the-pattern.png"><img src="/wp-content/uploads/2012/04/Morris-Pratt-more-than-one-repeating-letter-in-the-pattern.png" alt="Morris-Pratt more than one repeating letter in the pattern" title="Morris-Pratt more than one repeating letter in the pattern" width="622" height="461" class="size-full wp-image-3046" srcset="/wp-content/uploads/2012/04/Morris-Pratt-more-than-one-repeating-letter-in-the-pattern.png 622w, /wp-content/uploads/2012/04/Morris-Pratt-more-than-one-repeating-letter-in-the-pattern-300x222.png 300w" sizes="(max-width: 622px) 100vw, 622px" /></a><figcaption class="wp-caption-text">The next table contains the positions of repeating letters!</figcaption></figure>
<p>After we have this table of possible “next” positions we can start exploring the text for our pattern.</p>
<figure id="attachment_3027" style="width: 622px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Morris-Pratt.png"><img src="/wp-content/uploads/2012/04/Morris-Pratt.png" alt="Morris-Pratt" title="Morris-Pratt" width="622" height="550" class="size-full wp-image-3027" srcset="/wp-content/uploads/2012/04/Morris-Pratt.png 622w, /wp-content/uploads/2012/04/Morris-Pratt-300x265.png 300w" sizes="(max-width: 622px) 100vw, 622px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<h2>Implementation</h2>
<p>Implementing Morris-Pratt isn’t difficult. First we have to preprocess the pattern and then perform the search. The following <a href="/category/php/" title="PHP on stoimen.com">PHP</a> code shows you how to do that.</p>
<pre lang="PHP">
/**
 * Pattern
 * 
 * @var string
 */
$pattern = 'mollis';

/**
 * Text to search
 * 
 * @var string
 */
$text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eleifend nisi viverra ipsum elementum porttitor quis at justo. Aliquam ligula felis, dignissim sit amet lobortis eget, lacinia ac augue. Quisque nec est elit, nec ultricies magna. Ut mi libero, dictum sit amet mollis non, aliquam et augue';

/**
 * Preprocess the pattern and return the "next" table
 * 
 * @param string $pattern
 */
function preprocessMorrisPratt($pattern, &$nextTable)
{
	$i = 0;
	$j = $nextTable[0] = -1;
	$len = strlen($pattern);
	
	while ($i < $len) {
		while ($j > -1 && $pattern[$i] != $pattern[$j]) {
			$j = $nextTable[$j];
		}
		
		$nextTable[++$i] = ++$j;
	}
}

/**
 * Performs a string search with the Morris-Pratt algorithm
 * 
 * @param string $text
 * @param string $pattern
 */
function MorrisPratt($text, $pattern)
{
	// get the text and pattern lengths
	$n = strlen($text);
	$m = strlen($pattern);
	$nextTable = array();
	
	// calculate the next table
	preprocessMorrisPratt($pattern, $nextTable);
	
	$i = $j = 0;
	while ($j < $n) {
		while ($i > -1 && $pattern[$i] != $text[$j]) {
			$i = $nextTable[$i];
		}
		$i++;
		$j++;
		if ($i >= $m) {
			return $j - $i;
		}
	}
	return -1;
}

// 275
echo MorrisPratt($text, $pattern);
</pre>
<h2>Complexity</h2>
<p>This algorithm needs some time and space for preprocessing. Thus the preprocess of the pattern can be done in O(m), where m is the length of the pattern, while the search itself needs O(m+n). The good news is that you can do the preprocess only once and then perform the search as many times as you wish!</p>
<p>The following chart shows the complexity O(n+m) compared with O(nm) for 5 letter patterns.</p>
<figure id="attachment_3026" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/04/Morris-Pratt-complexity.png"><img src="/wp-content/uploads/2012/04/Morris-Pratt-complexity.png" alt="Morris-Pratt complexity" title="Morris-Pratt complexity" width="600" height="371" class="size-full wp-image-3026" srcset="/wp-content/uploads/2012/04/Morris-Pratt-complexity.png 600w, /wp-content/uploads/2012/04/Morris-Pratt-complexity-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">After pre-processing with O(m) the complexity of searching is O(n+m). You can see on the chart how effective is Morris-Pratt string searching compared to brute force string searching!</figcaption></figure>
<h2>Application</h2>
<h3>Why it&#8217;s cool</h3>
<ol>
<li>Its searching complexity is O(m+n) which is faster than brute force and Rabin-Karp</li>
<li>It’s fairly easy to implement</li>
</ol>
<h3>Why it isn’t cool</h3>
<ol>
<li>It needs additional space and time &#8211; O(m) for pre-processing</li>
<li>It can be optimized a bit (Knuth-Morris-Pratt)</li>
</ol>
<h2>Final Words</h2>
<p>Obviously this algorithm is quite useful because it improves in some very elegant manner the brute force matching. In the other hand you must know that there are faster string searching algorithms like the Boyer-Moore algorithm. However the Morris-Pratt algorithm can be quite useful in many cases, so understanding its principles can be very handy.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/04/17/computer-algorithms-boyer-moore-string-search-and-matching/" rel="bookmark" title="Computer Algorithms: Boyer-Moore String Searching">Computer Algorithms: Boyer-Moore String Searching </a></li>
<li><a href="/2012/04/02/computer-algorithms-rabin-karp-string-searching/" rel="bookmark" title="Computer Algorithms: Rabin-Karp String Searching">Computer Algorithms: Rabin-Karp String Searching </a></li>
<li><a href="/2012/03/27/computer-algorithms-brute-force-string-matching/" rel="bookmark" title="Computer Algorithms: Brute Force String Matching">Computer Algorithms: Brute Force String Matching </a></li>
<li><a href="/2011/08/18/powerful-php-less-known-string-manipulation/" rel="bookmark" title="Powerful PHP: Less Known String Manipulation">Powerful PHP: Less Known String Manipulation </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/04/09/computer-algorithms-morris-pratt-string-searching/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
