Click here to Skip to main content
15,886,137 members
Articles / Programming Languages / C#

A .NET implementation for the Knuth-Moris-Pratt (KMP) algorithm

Rate me:
Please Sign up or sign in to vote.
4.67/5 (5 votes)
4 Apr 2009CPOL3 min read 47.1K   1.3K   26  
A .NET implementation for the Knuth-Moris-Pratt (KMP) algorithm.
// ==================================================================
// KMPUtil.cs
// ==================================================================
// � Copyright nairooz001@yahoo.com
// ==================================================================
// ================================================================================================ 
// Maintenance log - insert most recent change descriptions at top 
// 
// Date             Defect #           Who					  Description
//
// 13-Dec-08                          Nairooz NIlafdeen       Initial File Creation
// ================================================================================================
using System;
using System.Collections;

namespace Nairooz.KMP
{
	/// <summary>
	/// Summary description for KMPUtil.
	/// </summary>
	public sealed class KMPUtil
	{
		private KMPUtil(){}

		/// <summary>
		/// Finds all the occurences a pattern in a a string
		/// </summary>
		/// <param name="pattern">The pattern to search for</param>
		/// <param name="targetString">The target string to search for</param>
		/// <returns>
		/// Return an Arraylist containing the indexs where the 
		/// patternn occured
		/// </returns>
		public static ArrayList GetAllOccurences(string pattern, string targetString)
		{
			return GetOccurences(pattern, targetString);
		}

		/// <summary>
		/// Finds all the occurences a pattern in a string in reverse order
		/// </summary>
		/// <param name="pattern">The pattern to search for</param>
		/// <param name="targetString">
		/// The target string to search for. This string is actually reversed
		/// </param>
		/// <returns>
		/// Return an Arraylist containing the indexs where the 
		/// patternn occured
		/// </returns>
		public static ArrayList GetOccurencesForReverseString(string pattern, string targetString)
		{
            char[] array = pattern.ToCharArray();
			Array.Reverse(array);

			return GetOccurences(new string(array), targetString);			
		}

		/// <summary>
		/// Finds all the occurences a pattern in a a string
		/// </summary>
		/// <param name="pattern">The pattern to search for</param>
		/// <param name="targetString">The target string to search for</param>
		/// <returns>
		/// Return an Arraylist containing the indexs where the 
		/// patternn occured
		/// </returns>
		private static ArrayList GetOccurences(string pattern , string targetString)
		{
			ArrayList result;
			int[] transitionArray ;
			char[] charArray;
			char[] patternArray;

			charArray					= targetString.ToLower().ToCharArray();
			patternArray				= pattern.ToLower().ToCharArray();
			result					    = new ArrayList();

			PrefixArray  prefixArray	= new PrefixArray(pattern);
			transitionArray				= prefixArray.TransitionArray;
						
			//Keeps track of the pattern index
			int k = 0;

			for(int i = 0; i < charArray.Length; i++)
			{
				//If there is a match
				if(charArray[i] == patternArray[k])	
				{
					//Move the pattern index by one
					k++;
				}
				else
				{
					//There is a mismatch..so move the pattern 
					
					//The amount to move through the pattern	
					int prefix = transitionArray[k];

					//if the current char does not match
					//the char in the pattern that concides
					//when moved then shift the pattern entirley, so 
					//we dont make a unnecssary comparision
					if(prefix + 1 > patternArray.Length && 
						charArray[i] != patternArray[prefix + 1])
					{

						k = 0;
					}
					else
					{
						k = prefix;
					}
				}

				//A complet match, if kis
				//equal to pattern length
				if(k == patternArray.Length)
				{
					//Add it to our result
					result.Add(i - (patternArray.Length - 1));

					//Set k as if the next character is a mismatch
					//therefore we dont mis out any other containing
					//pattern
					k  = transitionArray[k - 1];
				}
			}	
	
			return result;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Sri Lanka Sri Lanka
I am a Senior Software Engineer at Virtusa, Sri Lanka, I have an IT degree from University of Colombo and currently reading for my Master in Computer Science at the same University.

Comments and Discussions