1
1
//: Playground - noun: a place where people can play
2
2
3
- func ZetaAlgorithm( ptnr: String ) -> [ Int ] ? {
3
+ // last checked with Xcode 9.0b4
4
+ #if swift(>=4.0)
5
+ print ( " Hello, Swift4! " )
6
+ #endif
4
7
8
+ func ZetaAlgorithm( ptnr: String ) -> [ Int ] ? {
9
+
5
10
let pattern = Array ( ptnr. characters)
6
11
let patternLength : Int = pattern. count
7
-
12
+
8
13
guard patternLength > 0 else {
9
14
return nil
10
15
}
11
-
16
+
12
17
var zeta : [ Int ] = [ Int] ( repeating: 0 , count: patternLength)
13
-
18
+
14
19
var left : Int = 0
15
20
var right : Int = 0
16
21
var k_1 : Int = 0
17
22
var betaLength : Int = 0
18
23
var textIndex : Int = 0
19
24
var patternIndex : Int = 0
20
-
25
+
21
26
for k in 1 ..< patternLength {
22
27
if k > right {
23
28
patternIndex = 0
24
-
29
+
25
30
while k + patternIndex < patternLength &&
26
31
pattern [ k + patternIndex] == pattern [ patternIndex] {
27
- patternIndex = patternIndex + 1
32
+ patternIndex = patternIndex + 1
28
33
}
29
-
34
+
30
35
zeta [ k] = patternIndex
31
-
36
+
32
37
if zeta [ k] > 0 {
33
38
left = k
34
39
right = k + zeta[ k] - 1
35
40
}
36
41
} else {
37
42
k_1 = k - left + 1
38
43
betaLength = right - k + 1
39
-
44
+
40
45
if zeta [ k_1 - 1 ] < betaLength {
41
46
zeta [ k] = zeta [ k_1 - 1 ]
42
47
} else if zeta [ k_1 - 1 ] >= betaLength {
43
48
textIndex = betaLength
44
49
patternIndex = right + 1
45
-
50
+
46
51
while patternIndex < patternLength && pattern [ textIndex] == pattern [ patternIndex] {
47
52
textIndex = textIndex + 1
48
53
patternIndex = patternIndex + 1
@@ -57,54 +62,54 @@ func ZetaAlgorithm(ptnr: String) -> [Int]? {
57
62
}
58
63
59
64
extension String {
60
-
65
+
61
66
func indexesOf( ptnr: String ) -> [ Int ] ? {
62
-
67
+
63
68
let text = Array ( self . characters)
64
69
let pattern = Array ( ptnr. characters)
65
-
70
+
66
71
let textLength : Int = text. count
67
72
let patternLength : Int = pattern. count
68
-
73
+
69
74
guard patternLength > 0 else {
70
75
return nil
71
76
}
72
-
77
+
73
78
var suffixPrefix : [ Int ] = [ Int] ( repeating: 0 , count: patternLength)
74
79
var textIndex : Int = 0
75
80
var patternIndex : Int = 0
76
81
var indexes : [ Int ] = [ Int] ( )
77
-
82
+
78
83
/* Pre-processing stage: computing the table for the shifts (through Z-Algorithm) */
79
84
let zeta = ZetaAlgorithm ( ptnr: ptnr)
80
-
85
+
81
86
for patternIndex in ( 1 ..< patternLength) . reversed ( ) {
82
87
textIndex = patternIndex + zeta![ patternIndex] - 1
83
88
suffixPrefix [ textIndex] = zeta![ patternIndex]
84
89
}
85
-
90
+
86
91
/* Search stage: scanning the text for pattern matching */
87
92
textIndex = 0
88
93
patternIndex = 0
89
-
94
+
90
95
while textIndex + ( patternLength - patternIndex - 1 ) < textLength {
91
-
96
+
92
97
while patternIndex < patternLength && text [ textIndex] == pattern [ patternIndex] {
93
98
textIndex = textIndex + 1
94
99
patternIndex = patternIndex + 1
95
100
}
96
-
101
+
97
102
if patternIndex == patternLength {
98
103
indexes. append ( textIndex - patternIndex)
99
104
}
100
-
105
+
101
106
if patternIndex == 0 {
102
107
textIndex = textIndex + 1
103
108
} else {
104
109
patternIndex = suffixPrefix [ patternIndex - 1 ]
105
110
}
106
111
}
107
-
112
+
108
113
guard !indexes. isEmpty else {
109
114
return nil
110
115
}
0 commit comments