using System.Collections.Generic;
using System.Text.RegularExpressions;
static bool ValidateInputParameters(string inputStr, string pattern, ref string errMsg)
if (inputStr == null || inputStr.Length < 2)
errMsg = " Error: Invalid Input Parameters. The input string is empty or invalid.";
if (pattern == null || !(int.TryParse(pattern, out pLength))) {
errMsg = " Error: Invalid Input Parameters. The pattern length is empty or invalid.";
errMsg = " Error: Invalid Input Parameters. The pattern length has to be atleast 1.";
if (inputStr.Length <= pLength)
errMsg = " Error: Invalid Input Parameters. The length of the pattern should be less than the length of the input string.";
static void FindPattern_BruteForce(string inputStr, string pattern, Dictionary<string, int> patternList)
int pLength = Convert.ToInt32(pattern);
for (int i = 0; i < inputStr.Length - pLength; i++)
searchString = inputStr.Substring(i, pLength);
if (!patternList.ContainsKey(searchString))
for (int j = i + 1; j <= (inputStr.Length - pLength); j++)
patternString = inputStr.Substring(j, pLength);
if (searchString == patternString)
patternList.Add(searchString, patternCount);
static void FindPattern_UsingRecursion(string inputStr, string pattern, Dictionary<string, int> patternList)
int pLength = Convert.ToInt32(pattern);
for (int i = 0; i < inputStr.Length - pLength; i++)
searchString = inputStr.Substring(i, pLength);
if (!patternList.ContainsKey(searchString))
GetPatternCount(inputStr.Substring(i + 1), searchString, ref patternCount);
patternList.Add(searchString, patternCount);
static void GetPatternCount(string inputStr, string patternStr, ref int patternCount)
if (inputStr == patternStr)
if (inputStr.IndexOf(patternStr) != -1)
GetPatternCount(inputStr.Substring(inputStr.IndexOf(patternStr) + 1), patternStr, ref patternCount);
static void FindPattern_UsingRegex(string inputStr, string pattern, Dictionary<string, int> patternList)
int pLength = Convert.ToInt32(pattern);
for (int i = 0; i < inputStr.Length - pLength; i++)
string searchString = inputStr.Substring(i, pLength);
if (!patternList.ContainsKey(searchString))
string regexExpr = inputStr;
var patternMatch = Regex.Match(regexExpr, Regex.Escape(searchString));
while (patternMatch.Success)
regexExpr = regexExpr.Substring(patternMatch.Index + 1);
patternMatch = Regex.Match(regexExpr, Regex.Escape(searchString));
patternList.Add(searchString, patternCount);
static void FindPattern_UsingBayerMooreAlgo(string inputStr, string pattern, Dictionary<string, int> patternList)
int pLength = Convert.ToInt32(pattern);
Dictionary<char, int> badMatchTable = new Dictionary<char, int>();
for (int i = 0; i < inputStr.Length - pLength; i++)
string searchString = inputStr.Substring(i, pLength);
if (!patternList.ContainsKey(searchString))
for (int j = 0; j < searchString.Length; j++)
shiftPos = Math.Max(1, (pLength - j - 1));
if (badMatchTable.TryGetValue(searchString[j], out value))
badMatchTable[searchString[j]] = shiftPos;
badMatchTable.Add(searchString[j], shiftPos);
BayerMooreSearch(searchString, inputStr.Substring(i + 1), badMatchTable, patternList);
static void BayerMooreSearch(string pString, string ipString, IDictionary<char,int> bmTable, IDictionary<string, int> pList)
int pLength = pString.Length;
int patternIndex = pLength - 1;
int inputIndex = pLength - 1;
int startIndex = inputIndex;
while (inputIndex < ipString.Length)
if (pString[patternIndex] == ipString[inputIndex])
while(patternIndex >= 0 && isMatch)
if (pString[patternIndex] == ipString[inputIndex])
if (bmTable.TryGetValue(ipString[inputIndex], out value))
inputIndex = startIndex + value;
inputIndex = startIndex + pLength;
if (pList.TryGetValue(pString, out value))
pList[pString] = value + 1;
inputIndex = startIndex + 1;
if (bmTable.TryGetValue(ipString[inputIndex], out value))
inputIndex = startIndex + value;
inputIndex = startIndex + pLength;
patternIndex = pLength - 1;
static void FindPattern_UsingBinaryTree(string inputStr, string pattern, Dictionary<string, int> patternList)
int pLength = Convert.ToInt32(pattern);
for (int i = 0; i <= inputStr.Length - pLength; i++)
string searchString = inputStr.Substring(i, pLength);
if (BinaryTreeSearch(searchString))
if (patternList.TryGetValue(searchString, out value))
patternList[searchString] = value + 1;
patternList.Add(searchString, 2);
public static bool BinaryTreeSearch(string patternStr)
bool stringFound = false;
bool nodeCreated = false;
BinaryTreeNode nextNode = RootNode;
while (!stringFound && !nodeCreated && nextNode != null)
int comparisonResult = string.Compare(patternStr, nextNode.pData);
if(comparisonResult == 0)
if (comparisonResult > 0)
if(nextNode.right_node == null)
BinaryTreeNode newNode = new BinaryTreeNode(patternStr);
nextNode.right_node = newNode;
nextNode = nextNode.right_node;
if (nextNode.left_node == null)
BinaryTreeNode newNode = new BinaryTreeNode(patternStr);
nextNode.left_node = newNode;
nextNode = nextNode.left_node;
RootNode = new BinaryTreeNode(patternStr);
public static void CleanUpBinaryTree(BinaryTreeNode startNode)
if (startNode.left_node == null & startNode.right_node == null)
if(startNode.left_node != null)
CleanUpBinaryTree(startNode.left_node);
startNode.left_node = null;
if (startNode.right_node != null)
CleanUpBinaryTree(startNode.right_node);
startNode.right_node = null;
public class BinaryTreeNode
public BinaryTreeNode left_node;
public BinaryTreeNode right_node;
public BinaryTreeNode(string data)
public static BinaryTreeNode RootNode { get; set; }
static void DisplayResult(string message, Dictionary<string, int> result)
Console.WriteLine("\n\n\t*********************************************\n\t{0} \n", message);
Console.WriteLine("\tNo matching patterns found.");
Console.WriteLine("\tNumber of patterns found = " + result.Count + "\n");
Console.WriteLine("\t\tPattern String \t\t| \tCount");
Console.WriteLine("\t____________________________________________________\n");
foreach (KeyValuePair<string, int> patternEntry in result)
Console.WriteLine("\t\t\t\"" + patternEntry.Key + "\"\t \t\t\t " + patternEntry.Value);
public static void Main(string[] args)
string inputString, patternLengthStr, errorMsg = string.Empty;
Dictionary<string, int> patternMatchResult = new Dictionary<string, int>();
Console.WriteLine("\n\t Welcome to Pattern Matching/Repeat Approach \n");
Console.WriteLine("\t Assumptions: ");
Console.WriteLine("\t\t 1) Pattern matching is case-sensitive.");
Console.WriteLine("\t\t 2) Input string does not have any trailing or leading white spaces.");
Console.WriteLine("\t\t 3) Empty white space in a string between 2 words is considered a valid character. \n");
Console.Write("\t Enter Input String: ");
inputString = Console.ReadLine().Trim();
Console.Write("\t Enter Pattern Length: ");
patternLengthStr = Console.ReadLine().Trim();
if (!ValidateInputParameters(inputString, patternLengthStr, ref errorMsg))
Console.WriteLine("\n\t{0}", errorMsg);
FindPattern_BruteForce(inputString, patternLengthStr, patternMatchResult);
DisplayResult("Output from Approach 1 - Brute Force:", patternMatchResult);
patternMatchResult.Clear();
FindPattern_UsingRecursion(inputString, patternLengthStr, patternMatchResult);
DisplayResult("Output from Approach 2 - Using Recursion:", patternMatchResult);
patternMatchResult.Clear();
FindPattern_UsingRegex(inputString, patternLengthStr, patternMatchResult);
DisplayResult("Output from Approach 3 - Using Regex:", patternMatchResult);
patternMatchResult.Clear();
FindPattern_UsingBayerMooreAlgo(inputString, patternLengthStr, patternMatchResult);
DisplayResult("Output from Approach 4 - Using Bayer-Moore Algorithm:", patternMatchResult);
patternMatchResult.Clear();
FindPattern_UsingBinaryTree(inputString, patternLengthStr, patternMatchResult);
DisplayResult("Output from Approach 5 - Using Binary Tree:", patternMatchResult);
Console.WriteLine("\n\n\t-----------------------------End of Program-----------------------------");
Console.WriteLine("Application Exception: {0} \n StackTrace: {1}", ex.Message, ex.StackTrace);
CleanUpBinaryTree(RootNode);