-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
ZblockSubstringSearch.cs
68 lines (60 loc) · 1.7 KB
/
ZblockSubstringSearch.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
namespace Algorithms.Strings.PatternMatching;
/// <summary>Implementation Z-block substring search.
/// </summary>
public static class ZblockSubstringSearch
{
/// <summary>
/// This algorithm finds all occurrences of a pattern in a text in linear time - O(m+n).
/// </summary>
public static int FindSubstring(string pattern, string text)
{
var concatStr = $"{pattern}${text}";
var patternLength = pattern.Length;
var n = concatStr.Length;
var zArray = new int[n];
var left = 0;
var right = 0;
for(var i = 1; i < n; i++)
{
if(i > right)
{
left = i;
right = ComputeNewRightValue(concatStr, n, left, i);
zArray[i] = right - left;
right--;
}
else
{
var k = i - left;
if (zArray[k] < (right - i + 1))
{
zArray[i] = zArray[k];
}
else
{
left = i;
right = ComputeNewRightValue(concatStr, n, left, right);
zArray[i] = right - left;
right--;
}
}
}
var found = 0;
foreach(var z_value in zArray)
{
if(z_value == patternLength)
{
found++;
}
}
return found;
}
private static int ComputeNewRightValue(string concatStr, int n, int left, int right)
{
while (right < n && concatStr[right - left].Equals(concatStr[right]))
{
right++;
}
return right;
}
}