11pub trait SliceExt<T> {
22 fn index_of(sub_arr:[T]) Option<i64>;
3+ fn index_of_kmp(sub_arr:[T]) Option<i64>;
34 fn len() i64;
45 fn slice(start: i64, end: i64) [T];
56 fn copy(to:[T], len:i64) Result<()|SliceOutOfIdxErr>;
@@ -9,6 +10,25 @@ pub struct SliceOutOfIdxErr {
910
1011}
1112
13+
14+ fn arr_next<T:Eq<T>>(arr:[T]) [i64] {
15+ let len = arr.len();
16+ let next = [0* len];
17+ next[0] = -1;
18+ let i = 0;
19+ let j = -1;
20+ while i < len - 1 {
21+ if j == -1 || arr[i].eq(&arr[j]) {
22+ i = i + 1;
23+ j = j + 1;
24+ next[i] = j;
25+ } else {
26+ j = next[j];
27+ }
28+ }
29+ return next;
30+ }
31+
1232use core::eq::Eq;
1333impl<T:Eq<T>> SliceExt<T> for [T] {
1434 /// # index_of
@@ -17,6 +37,18 @@ impl<T:Eq<T>> SliceExt<T> for [T] {
1737 fn index_of(sub_arr:[T]) Option<i64> {
1838 let len = self.len();
1939 let sub_len = sub_arr.len();
40+
41+ // Calculate the expected cost of both algorithms
42+ let cost_index_of = len * sub_len/2;
43+ let cost_index_of_kmp = len + sub_len;
44+
45+ // Choose the algorithm with the lower expected cost
46+ if cost_index_of_kmp < cost_index_of {
47+ return self.index_of_kmp(sub_arr);
48+ }
49+
50+
51+
2052 if sub_len > len || sub_len == 0{
2153 return None{};
2254 }
@@ -38,6 +70,31 @@ impl<T:Eq<T>> SliceExt<T> for [T] {
3870
3971 }
4072
73+
74+ fn index_of_kmp(sub_arr:[T]) Option<i64> {
75+ let len = self.len();
76+ let sub_len = sub_arr.len();
77+ if sub_len > len || sub_len == 0{
78+ return None{};
79+ }
80+ let next = arr_next(sub_arr);
81+ let i = 0;
82+ let j = 0;
83+ while i < len {
84+ if j == -1 || (*self)[i].eq(&sub_arr[j]) {
85+ i = i + 1;
86+ j = j + 1;
87+ } else {
88+ j = next[j];
89+ }
90+ if j == sub_len {
91+ return i - sub_len;
92+ }
93+ }
94+ return None{};
95+ }
96+
97+
4198 /// # len
4299 ///
43100 /// Get the length of the array.
0 commit comments