Sunday Algorithm - Index was outside the bounds of the array [duplicate] - c#

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 3 years ago.
I have this Sunday Algorithm, which checks some occurrences in some text.
class Program
{
static int alphabet = 512;
static int[] table = new int[alphabet];
static int[] occurence(string pattern)
{
for(char a = (char)0; a<(char)alphabet;a++)
{
table[(int)a] = -1;
}
for(int i = 0; i< pattern.Length;i++)
{
char a = pattern[i];
table[(int)a] = i;
}
return table;
}
public static int Sunday(string text, string pattern)
{
Stopwatch timer = new Stopwatch();
timer.Start();
int k = 0;
int i = 0;
int[] table = new int[pattern.Length];
table = occurence(pattern);
while(i <= text.Length - pattern.Length)
{
int j = 0;
while(j<pattern.Length && text[i+j] == pattern[j])
{
j++;
}
if(j==pattern.Length)
{
k++;
}
i += pattern.Length;
if(i<text.Length)
{
i -= table[(int)text[i]];
}
}
timer.Stop();
Console.WriteLine(timer.Elapsed);
return k;
}
static void Main(string[] args)
{
string text = File.ReadAllText(#"C:\Users\Bacho\Desktop\Studies\Advanced Algorithms\Test Patterns\Book1.txt");
string pattern = "frankenstein";
Console.WriteLine(Sunday(text, pattern));
}
}
This is my algorithm, which works well on small input of text. In the code, I try to read a text file which consists of roughly 80 000 words and 450 000 characters. I get this exception:
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Sunday1.Program.Sunday(String text, String pattern) in C:\Users\Bacho\Desktop\Studies\Advanced Algorithms\Sunday1\Sunday1\Program.cs:line 55
at Sunday1.Program.Main(String[] args) in C:\Users\Bacho\Desktop\Studies\Advanced Algorithms\Sunday1\Sunday1\Program.cs:line 68
..at the following line:
i -= table[(int)text[i]];
Is it because it can not fit in string or is it something else?
Changing the algorithm to read and check line by line may be a solution, but is there a way to avoid it?

A char has a length of two bytes or 16 bits not 9. So I guess your alphabet should therefore probably be 65336 or simply char.MaxValue instead of 512.
Also there's no need of the static fields. You can make them local to occurence(). And in Sunday, you don't need to initialize table with new int[pattern.Length], you can directly use occurence(pattern).
class Program
{
static int[] occurence(string pattern)
{
int[] table = new int[char.MaxValue + 1];
for (int a = 0; a < char.MaxValue + 1; a++)
{
table[a] = -1;
}
for (int i = 0; i < pattern.Length; i++)
{
char a = pattern[i];
table[(int)a] = i;
}
return table;
}
public static int Sunday(string text, string pattern)
{
Stopwatch timer = new Stopwatch();
timer.Start();
int k = 0;
int i = 0;
int[] table = occurence(pattern);
while (i <= text.Length - pattern.Length)
{
int j = 0;
while (j < pattern.Length && text[i + j] == pattern[j])
{
j++;
}
if (j == pattern.Length)
{
k++;
}
i += pattern.Length;
if (i < text.Length)
{
i -= table[(int)text[i]];
}
}
timer.Stop();
Console.WriteLine(timer.Elapsed);
return k;
}
static void Main(string[] args)
{
string text = File.ReadAllText(#"C:\Users\Bacho\Desktop\Studies\Advanced Algorithms\Test Patterns\Book1.txt");
string pattern = "frankenstein";
Console.WriteLine(Sunday(text, pattern));
}
}

Related

Unable to move the hash sign the right side

I'm unable to move the hash sign to the right to get the below shape.
My below code is working not as expected but I need to get the below shape.
Please how do I do it?
#
##
###
####
#####
######
#######
public class MyProgramTest
{
public static void StaircaseChallenge(int n)
{
for (int i = 1; i <= n; i++) {
Console.WriteLine(MySpace(i) + HashSign(i));
}
}
public static string HashSign(int n)
{
string t = "";
for (int i = 1; i <= n; i++) {
t += "#";
}
return t;
}
public static string MySpace(int n)
{
string t = "/t";
for (int i = 1; i < n; i++)
{
t += " ";
}
return t;
}
}
Try this:
public class MyProgramTest
{
public static void StaircaseChallenge(int n)
{
for (int i = 1; i <= n; i++)
{
Console.WriteLine(" ".PadLeft(n - i+1, ' ')+"#".PadLeft(i,'#'));
}
}
Or make few changes to your code:
public class MyProgramTest
{
public static void StaircaseChallenge(int n)
{
for (int i = 1; i <= n; i++)
{
Console.WriteLine(MySpace(n - i + 1) + HashSign(i));
}
}
public static string HashSign(int n)
{
string t = "";
for (int i = 1; i <= n; i++)
{
t += "#";
}
return t;
}
public static string MySpace(int n)
{
string t = string.Empty;
for (int i = 1; i < n; i++)
{
t += " ";
}
return t;
}
}
A more memory efficient way would be using the StringBuilder class.
For this situation it's not critical, but nice to know.
// define the amount of steps
int n=8;
// amount of leading whitespaces, for later usage
int padding=0;
// this one is the "working" memory, initialized by n + padding whitespaces
StringBuilder currentLine=new StringBuilder(new string(' ',n+padding));
// it counts down from the last index to the one indicated by padding
for (int i = currentLine.Length-1; i >=padding; i--)
{
// replace the char at the current index with #; (here: always the index of the last whitespace)
currentLine[i]='#';
// display a copy of the current state on the console,
Console.WriteLine(currentLine.ToString());
}
Please change only few things in your code :
public class MyProgramTest
{
public static void StaircaseChallenge(int n)
{
for (int i = 1; i <= n; i++) {
Console.WriteLine(MySpace(i, n) + HashSign(i));
}
}
public static string HashSign(int n)
{
string t = "";
for (int i = 1; i <= n; i++) {
t += "#";
}
return t;
}
public static string MySpace(int m, int n)
{
string t = "";
for (int i = 1; i <= n - m; i++)
{
t += " ";
}
return t;
}
}
You have to pass more one variable is n (number of row) in MySpace() function for leave space. When you pass number of row in MySpace() function then it will leave (number of row - 1) space. So if you enter 5 then first time it will leave 4 space and then put "#" like wise.

I wrote a program to get the count of matching adjacent alphabets in a string

For the same 1 of the test cases have passed while all the other had failed. The failed ones test cases were of very long strings. but could not understand where did I go wrong.
The number of test cases and string is been read in the main function, and string gets passed to this function.
public static int getMaxScore(string jewels)
{
string temp=jewels;
int count=0;
for(int i=0;i<temp.Length-1;i++)
{
for(int j=i;j<temp.Length-1;j++)
{
if(jewels[i]==jewels[j+1])
{
temp=jewels.Remove(i,2);
count++;
}
else
{
continue;
}
}
}
return count;
}
for the passed 1, there were 2 test cases. In that, one being jewels="abcddcbd" and the other being "abcd". Expected Output was 3 for the first string and 0 for the second. however, i got the expected output for this test case. but failed all other ones(those are very long strings)
jewels="edmamjboxwzfjsgnmycuutvkhzerdiabcvzlnoazreuavyemxqwgyzdvrzyohamwamziqvdduequyyspfipvigooyqmwllvp"
Can somebody help me in knowing what is wrong in my code or how can I obtain the result I want?
Thanks in Advance!!!
Sounds a Jewel Quest puzzle. Checking a string for adjacent equal characters, remove them and increase the counter by 1. Removing the two characters from the string could produce a new one with adjacent equal characters so it must be checked again from the beginning to remove them, increase the counter, and do it all over again until no more.
public static int getMaxScore(string jewels)
{
var count = 0;
var max = jewels.Length;
var i = 0;
var chars = jewels.ToList();
var adj = 2; //<- Change to increase the number of adjacent chars.
while (i < max)
{
if (chars.Count >= adj && i <= chars.Count - adj &&
chars.Skip(i).Take(adj).Distinct().Count() == 1)
{
count++;
chars.RemoveRange(i, adj);
max = chars.Count;
i = 0;
}
else
i++;
}
return count;
}
Testing:
void TheCaller()
{
Console.WriteLine(getMaxScore("abcddcbd"));
Console.WriteLine(getMaxScore("abcd"));
Console.WriteLine(getMaxScore("edmamjboxwzfjsgnmycuutvkhzerdiabcvzlnoazreuavyemxqwgyzdvrzyohamwamziqvdduequyyspfipvigooyqmwllvp"));
}
Writes 3, 0, and 5 respectively.
public static int CountThings(string s)
{
if(s.Length < 2) { return 0; }
int n = 0;
for (int i = 0; i < s.Length - 1; i++)
{
if (s[i] == s[i + 1])
{
int start = i;
int end = i + 1;
while (s[start] == s[end] && start >= 0 && end <= s.Length - 1)
{
n++;
start--;
end++;
}
}
}
return n;
}
For grits and shins, here's a compact recursive version:
static void Main(string[] args)
{
string jewels = "edmamjboxwzfjsgnmycuutvkhzerdiabcvzlnoazreuavyemxqwgyzdvrzyohamwamziqvdduequyyspfipvigooyqmwllvp";
int score = getMaxScore(new StringBuilder(jewels));
Console.WriteLine($"jewels = {jewels}");
Console.WriteLine($"score = {score}");
Console.Write("Press Enter to Quit.");
Console.ReadLine();
}
static int getMaxScore(StringBuilder jewels)
{
for(int i=0; i<(jewels.Length-1); i++)
if (jewels[i]==jewels[i+1])
return 1 + getMaxScore(jewels.Remove(i, 2));
return 0;
}

How to reduce the memory usage of a C# console application project?

This is program consumes 36.50 MB of memory but I want it to be less than 32 MB
public static void CreateText(string text)
{
if (Convert.ToInt32(text.Length) <= 80)
{
int n;
string str = "";
string count = "";
char[] mas = text.ToCharArray();
for (int i = 0; i < Convert.ToInt32(mas.Length); i++)
{
if (int.TryParse(mas[i].ToString(), out n))
{
count += mas[i].ToString();
}
else
{
if (String.IsNullOrEmpty(count))
{
str += mas[i].ToString();
}
else
{
for (int j = 0; j < Convert.ToInt32(count); j++)
{
str += mas[i].ToString();
}
count = "";
}
}
}
Console.WriteLine(str);
} else {
Console.WriteLine("Error");
}
}
To reduce memory footprint you need to get read of temporary string objects generated by applying operation += against a string. String is immutable object in C#, so += creates new string. StringBuilder is mutable, so use it instead of string. You also need to have count as an int, not string or StringBuilder.
public static void CreateText(string mas)
{
if (mas.Length <= 80)
{
StringBuilder str;
int count;
for (int i = 0; i < mas.Length; i++)
{
if (mas[i] >= '0' && mas[i] <= '9')
count = count * 10 + mas[i] - '0';
else
{
if (count == 0)
str.Append(mas[i]);
else
{
for (int j = 0; j < count; j++)
str.Append(mas[i]);
count = 0;
}
}
}
Console.WriteLine(str.ToString());
}
else
Console.WriteLine("Error");
}
This probably isn't possible. Most of the RAM in a 36MB program is just core framework libraries. 36MB is nothing.
But I do see some potential improvements, the biggest of which are maintaining count as an integer rather than a string and using a string constructor and StringBuilder instead of appending to a string all the time:
public static void CreateText(string text)
{
if (text != null && text.Length <= 80)
{
int n; int count = 0;
StringBuilder result = new StringBuilder();
char[] mas = text.ToCharArray();
foreach(char c in text)
{
if (int.TryParse(c.ToString(), out n))
{
count = (count * 10) + n;
}
else
{
if (count == 0)
{
result.Append(c);
}
else
{
result.Append(new string(c, count));
count = 0;
}
}
}
Console.WriteLine(result.ToString());
} else {
Console.WriteLine("Error");
}
}
There is a potential bug there if you want to be able to explicitly set 0 repetition in the input string. If that's the case, we'll need something that is slightly less efficient, but should still have a big improvement over the original:
public static void CreateText(string text)
{
if (text != null && text.Length <= 80)
{
int n; int count = -1;
StringBuilder result = new StringBuilder();
char[] mas = text.ToCharArray();
foreach(char c in text)
{
if (int.TryParse(c.ToString(), out n))
{
if (count == -1) count = 0;
count = (count * 10) + n;
}
else
{
if (count == -1)
{
result.Append(c);
}
else
{
result.Append(new string(c, count));
count = -1;
}
}
}
Console.WriteLine(result.ToString());
} else {
Console.WriteLine("Error");
}
}
Try this:
public static void CreateText(string text)
{
if (text.Length <= 80)
{
var str = new StringBuilder();
var count = new StringBuilder();
for (int i = 0; i < text.Length; i++)
{
int n;
if (int.TryParse(text[i].ToString(), out n))
{
count.Append(text[i]);
}
else
{
if (String.IsNullOrEmpty(count.ToString()))
{
str.Append(text[i]);
}
else
{
for (int j = 0; j < Convert.ToInt32(count.ToString()); j++)
{
str.Append(text[i].ToString());
}
count.Clear();
}
}
}
Console.WriteLine(str);
}
else
{
Console.WriteLine("Error");
}
}
What I did was:
Remove the string contetantions (since they are immutable) and used a StringBuilder instead.
No need to convert to a char[] since your can treat a String as one (it implements the indexer)
Moved the n closed to used to it's only allocated if needed

Index Of Longest Run C#

I am trying to solve this question:
Write a function that finds the zero-based index of the longest run in a string. A run is a consecutive sequence of the same character. If there is more than one run with the same length, return the index of the first one.
For example, IndexOfLongestRun("abbcccddddcccbba") should return 6 as the longest run is dddd and it first appears on index 6.
Following what i have done:
private static int IndexOfLongestRun(string str)
{
char[] array1 = str.ToCharArray();
//Array.Sort(array1);
Comparer comparer = new Comparer();
int counter =1;
int maxCount = 0;
int idenxOf = 0;
for (int i =0; i<array1.Length-1 ; i++)
{
if (comparer.Compare(array1[i],array1[i+1]) == 0)
{
counter++;
}
else {
if(maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
counter = 1;
}
}
return idenxOf ;
}
}
public class Comparer : IComparer<char>
{
public int Compare(char firstChar, char nextChar)
{
return firstChar.CompareTo(nextChar);
}
}
The problem is that when i get to the last index for example "abbccaaaaaaaaaa"
which is a in this case, and when i=14 (taking this string as example) and when i<array1.Length-1 statment is false, the for loop jumps directrly to return indexOf; and return the wrong index, I am trying to find out how to push the forloop to continue the implementation so idenxOf could be changed to the right index. Any help please?
You could check whether a new best score is achieved for each iteration when current == previous. Minimally slower, but it allows you to write shorter code by omitting an extra check after the loop:
int IndexOfLongestRun(string input)
{
int bestIndex = 0, bestScore = 0, currIndex = 0;
for (var i = 0; i < input.Length; ++i)
{
if (input[i] == input[currIndex])
{
if (bestScore < i - currIndex)
{
bestIndex = currIndex;
bestScore = i - currIndex;
}
}
else
{
currIndex = i;
}
}
return bestIndex;
}
Promote the loop variable i to method scope and repeat the conditional block if (maxCount < counter) { ... } right after the loop exit. Thus, it executes one more time after the loop completes
private static int IndexOfLongestRun(string str)
{
char[] array1 = str.ToCharArray();
//Array.Sort(array1);
Comparer comparer = new Comparer();
int counter = 1;
int maxCount = 0;
int idenxOf = 0;
int i;
for (i = 0; i < array1.Length - 1; i++)
{
if (comparer.Compare(array1[i], array1[i + 1]) == 0)
{
counter++;
}
else
{
if (maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
counter = 1;
}
}
if (maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
return idenxOf;
}
As usual late, but joining the party. A natural classic algorithm:
static int IndexOfLongestRun(string input)
{
int longestRunStart = -1, longestRunLength = 0;
for (int i = 0; i < input.Length; )
{
var runValue = input[i];
int runStart = i;
while (++i < input.Length && input[i] == runValue) { }
int runLength = i - runStart;
if (longestRunLength < runLength)
{
longestRunStart = runStart;
longestRunLength = runLength;
}
}
return longestRunStart;
}
At the end you have both longest run index and length.
public static int IndexOfLongestRun(string str)
{
var longestRunCount = 1;
var longestRunIndex = 0;
var isNew = false;
var dic = new Dictionary<int, int>();
for (var i = 0; i < str.Length - 1; i++)
{
if (str[i] == str[i + 1])
{
if (isNew) longestRunIndex = i;
longestRunCount++;
isNew = false;
}
else
{
isNew = true;
dic.Add(longestRunIndex, longestRunCount);
longestRunIndex = 0;
longestRunCount = 1;
}
}
return dic.OrderByDescending(x => x.Value).First().Key;
}
This will return -1 if the string is empty and you have the flexibility of returning the index and the count depending on your specification.
string myStr = "aaaabbbbccccccccccccdeeeeeeeee";
var longestIndexStart = -1;
var longestCount = 0;
var currentCount = 1;
var currentIndexStart = 0;
for (var idx = 1; idx < myStr.Length; idx++)
{
if (myStr[idx] == myStr[currentIndexStart])
currentCount++;
else
{
if (currentCount > longestCount)
{
longestIndexStart = currentIndexStart;
longestCount = currentCount;
}
currentIndexStart = idx;
currentCount = 1;
}
}
return longestIndexStart;
The accepted answer from Kvam works great for small strings, but as the length approaches 100,000 characters (and perhaps this isn't needed), its efficiency wains.
public static int IndexOfLongestRun(string str)
{
Dictionary<string, int> letterCount = new Dictionary<string, int>();
for (int i = 0; i < str.Length; i++)
{
string c = str.Substring(i, 1);
if (letterCount.ContainsKey(c))
letterCount[c]++;
else
letterCount.Add(c, 1);
}
return letterCount.Values.Max();
}
This solution is twice as fast as Kvam's with large strings. There are, perhaps, other optimizations.

Count occurences in byte list/array using another byte list/array

I am trying to get a count of all the times a byte sequences occurs in another byte sequences. It cannot however re-use a bytes if it already counted them. For example given the string
k.k.k.k.k.k. let's assume the byte sequence was k.k it would then find only 3 occurrences rather than 5 because they would be broke down like: [k.k].[k.k].[k.k]. and not like [k.[k].[k].[k].[k].k] where they over lap and essentially just shift 2 to the right.
Ideally the idea is to get an idea how a compression dictionary or run time encoding might look. so the goal would be to get
k.k.k.k.k.k. down to just 2 parts, as (k.k.k.) is the biggest and best symbol you can have.
Here is source so far:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;
static class Compression
{
static int Main(string[] args)
{
List<byte> bytes = File.ReadAllBytes("ok.txt").ToList();
List<List<int>> list = new List<List<int>>();
// Starting Numbers of bytes - This can be changed manually.
int StartingNumBytes = bytes.Count;
for (int i = StartingNumBytes; i > 0; i--)
{
Console.WriteLine("i: " + i);
for (int ii = 0; ii < bytes.Count - i; ii++)
{
Console.WriteLine("ii: " + i);
// New pattern comes with refresh data.
List<byte> pattern = new List<byte>();
for (int iii = 0; iii < i; iii++)
{
pattern.Add(bytes[ii + iii]);
}
DisplayBinary(bytes, "red");
DisplayBinary(pattern, "green");
int matches = 0;
// foreach (var position in bytes.ToArray().Locate(pattern.ToArray()))
for (int position = 0; position < bytes.Count; position++) {
if (pattern.Count > (bytes.Count - position))
{
continue;
}
for (int iiii = 0; iiii < pattern.Count; iiii++)
{
if (bytes[position + iiii] != pattern[iiii])
{
//Have to use goto because C# doesn't support continue <level>
goto outer;
}
}
// If it made it this far, it has found a match.
matches++;
Console.WriteLine("Matches: " + matches + " Orig Count: " + bytes.Count + " POS: " + position);
if (matches > 1)
{
int numBytesToRemove = pattern.Count;
for (int ra = 0; ra < numBytesToRemove; ra++)
{
// Remove it at the position it was found at, once it
// deletes the first one, the list will shift left and you'll need to be here again.
bytes.RemoveAt(position);
}
DisplayBinary(bytes, "red");
Console.WriteLine(pattern.Count + " Bytes removed.");
// Since you deleted some bytes, set the position less because you will need to redo the pos.
position = position - 1;
}
outer:
continue;
}
List<int> sublist = new List<int>();
sublist.Add(matches);
sublist.Add(pattern.Count);
// Some sort of calculation to determine how good the symbol was
sublist.Add(bytes.Count-((matches * pattern.Count)-matches));
list.Add(sublist);
}
}
Display(list);
Console.Read();
return 0;
}
static void DisplayBinary(List<byte> bytes, string color="white")
{
switch(color){
case "green":
Console.ForegroundColor = ConsoleColor.Green;
break;
case "red":
Console.ForegroundColor = ConsoleColor.Red;
break;
default:
break;
}
for (int i=0; i<bytes.Count; i++)
{
if (i % 8 ==0)
Console.WriteLine();
Console.Write(GetIntBinaryString(bytes[i]) + " ");
}
Console.WriteLine();
Console.ResetColor();
}
static string GetIntBinaryString(int n)
{
char[] b = new char[8];
int pos = 7;
int i = 0;
while (i < 8)
{
if ((n & (1 << i)) != 0)
{
b[pos] = '1';
}
else
{
b[pos] = '0';
}
pos--;
i++;
}
//return new string(b).TrimStart('0');
return new string(b);
}
static void Display(List<List<int>> list)
{
//
// Display everything in the List.
//
Console.WriteLine("Elements:");
foreach (var sublist in list)
{
foreach (var value in sublist)
{
Console.Write("{0,4}", value);
}
Console.WriteLine();
}
//
// Display total count.
//
int count = 0;
foreach (var sublist in list)
{
count += sublist.Count;
}
Console.WriteLine("Count:");
Console.WriteLine(count);
}
static public int SearchBytePattern(byte[] pattern, byte[] bytes)
{
int matches = 0;
// precomputing this shaves some seconds from the loop execution
int maxloop = bytes.Length - pattern.Length;
for (int i = 0; i < maxloop; i++)
{
if (pattern[0] == bytes[i])
{
bool ismatch = true;
for (int j = 1; j < pattern.Length; j++)
{
if (bytes[i + j] != pattern[j])
{
ismatch = false;
break;
}
}
if (ismatch)
{
matches++;
i += pattern.Length - 1;
}
}
}
return matches;
}
}
Refer to the post to get the non binary of the file should be, here is the binary data:
011010110010111001101011001011100110101100101110011010110010111001101011001011100110101100101110 I am hope to have it smaller than how it started.
private static int CountOccurences(byte[] target, byte[] pattern)
{
var targetString = BitConverter.ToString(target);
var patternString = BitConverter.ToString(pattern);
return new Regex(patternString).Matches(targetString).Count;
}
With this solution you'd have access to the individual indexes that matched (while enumerating) or you could call Count() on the result to see how many matches there were:
public static IEnumerable<int> Find<T>(T[] pattern, T[] sequence, bool overlap)
{
int i = 0;
while (i < sequence.Length - pattern.Length + 1)
{
if (pattern.SequenceEqual(sequence.Skip(i).Take(pattern.Length)))
{
yield return i;
i += overlap ? 1 : pattern.Length;
}
else
{
i++;
}
}
}
Call it with overlap: false to solve your problem or overlap: true to see the overlapped matches (if you're interested.)
I have a couple of other methods with slightly different API (along with better performance) here, including one that work directly on streams of bytes.
quick and dirty with no regex. although i'm not sure if it answers the intent of the question, it should be relatively fast. i think i am going to run some timing tests against regex to see for sure the relative speeds:
private int CountOccurrences(string TestString, string TestPattern)
{
int PatternCount = 0;
int SearchIndex = 0;
if (TestPattern.Length == 0)
throw new ApplicationException("CountOccurrences: Unable to process because TestPattern has zero length.");
if (TestString.Length == 0)
return 0;
do
{
SearchIndex = TestString.IndexOf(TestPattern, SearchIndex);
if (SearchIndex >= 0)
{
++PatternCount;
SearchIndex += TestPattern.Length;
}
}
while ((SearchIndex >= 0) && (SearchIndex < TestString.Length));
return PatternCount;
}
private void btnTest_Click(object sender, EventArgs e)
{
string TestString1 = "k.k.k.k.k.k.k.k.k.k.k.k";
string TestPattern1 = "k.k";
System.Console.WriteLine(CountOccurrences(TestString1, TestPattern1).ToString()); // outputs 6
System.Console.WriteLine(CountOccurrences(TestString1 + ".k", TestPattern1).ToString()); // still 6
System.Console.WriteLine(CountOccurrences(TestString1, TestPattern1 + ".").ToString()); // only 5
}

Categories