1pub fn kmpm_str(text:&str,pattern:&str)->Option<usize>{
49 let sm_list = skipmap(pattern);
50 let mut cursor:usize= 0;
51 let mut prev_skip_step:usize = 0;
52 let endpoint = text.chars().count() - pattern.chars().count();
53 loop{
54 let mut skipstep:usize = 1;
55 let mut elseflag = false;
56 for i in 0..pattern.chars().count()-prev_skip_step{
58 if text.chars().nth(cursor+prev_skip_step+i)!=pattern.chars().nth(prev_skip_step+i){
60 skipstep=sm_list[i];
61 prev_skip_step = skipstep;
62 elseflag=true;
63 break;
64 }
65 }
66 if !elseflag{
67 return Some(cursor)
68 }
69 if cursor>endpoint{
70 return None
71 }
72 else {
73 cursor += skipstep;
74 }
75 }
76}
77
78
79pub fn kmpm_str_all(text:&str,pattern:&str)->Vec<usize>{
113 let mut rarr:Vec<usize> = Vec::new();
114 let sm_list = skipmap(pattern);
115 let mut cursor:usize= 0;
116 let mut prev_skip_step:usize = 0;
117 let endpoint = text.chars().count() - pattern.chars().count();
118 loop{
119 let mut skipstep:usize = 1;
120 let mut elseflag = false;
121 for i in 0..pattern.chars().count()-prev_skip_step{
122 if text.chars().nth(cursor+prev_skip_step+i)!=pattern.chars().nth(prev_skip_step+i){
123 skipstep=sm_list[i];
124 prev_skip_step = skipstep;
125 elseflag = true;
126 break;
127 }
128 }
129 if !elseflag{
130 rarr.push(cursor);
131 }
132 if cursor>endpoint{
133 return rarr
134 }else {
135 cursor += skipstep;
136 }
137 }
138}
139
140pub fn kmpm_str_nad(text:&str,pattern:&str,cursor_start:usize)->Vec<usize>{
169 let mut rarr:Vec<usize> = Vec::new();
170 let sm_list = skipmap(pattern);
171 let mut cursor:usize= cursor_start;
172 let mut prev_skip_step:usize = 0;
173 let endpoint = text.chars().count() - pattern.chars().count();
174 loop{
175 let mut skipstep:usize = 1;
176 let mut elseflag = false;
177 for i in 0..pattern.chars().count()-prev_skip_step{
180 if text.chars().nth(cursor+prev_skip_step+i)!=pattern.chars().nth(prev_skip_step+i){
181 skipstep=sm_list[i];
182 prev_skip_step = skipstep;
183 elseflag = true;
184 break;
185 }
186 }
187 if !elseflag{
188 println!("cursor {}\nskipstep {}\nprev_skip_step {}\n========",cursor,skipstep,prev_skip_step);
189 rarr.push(cursor);
190 }else {
191 println!("cursor {}\nskipstep {}\nprev_skip_step {}\n========",cursor,skipstep,prev_skip_step);
192 }
193 if cursor>endpoint{
194 return rarr;
195 }else {
196 if !elseflag{
197 cursor += skipstep + pattern.len();
198 }else {
199 cursor += skipstep;
200 }
201 }
202 }
203}
204
205
206fn dup(txt0:&Vec<char>,txt1:&Vec<char>,gap:usize)->bool{
207 let diflen = txt0.len()-gap;
208 let dig_txt0 = &txt0[gap..];
209 let dig_txt1 = &txt1[..diflen];
210 dig_txt0==dig_txt1
211}
212
213fn capable_gap(txt0:&Vec<char>,txt1:&Vec<char>)->usize{
214 let txt0_len = txt0.len();
215 if txt0_len==0{
216 return 1;
217 }
218 for i in 1..txt0_len{
219 if dup(&txt0, &txt1, i){
220 return i;
221 }
222 }
223 txt0_len
224}
225
226fn skipmap(txt:&str)->Vec<usize>{
227 let txt_vec:Vec<char>= txt.chars().collect();
228 let arr:Vec<usize> = (0..txt.chars().count())
229 .map(
230 |i|capable_gap(
231 &txt_vec[..i].to_vec(),
232 &txt_vec
233 )
234 )
235 .collect();
236 return arr;
237}
238
239
240#[cfg(test)]
241mod tests {
242
243 use super::*;
244
245 #[test]
246 fn test00(){
247 let text = "hello world";
248 let pattern ="world";
249 let ctr = kmpm_str(text, pattern);
250 match ctr {
251 Some(cursor)=>{
252 assert!(cursor==6);
253 println!("matched index {}",cursor)
254 }
255 None=>{
256 println!("\"{}\" does not match",pattern);
257 }
258 }
259 }
260
261 #[test]
262 fn test01(){
263 let text = "........................失敗...fosososos";
264 let pattern ="失敗";
265 let ctr = kmpm_str(text, pattern);
266 match ctr {
267 Some(cursor)=>{
268 assert!(cursor==24);
269 println!("matched index {}",cursor)
270 }
271 None=>{
272 println!("\"{}\" does not match",pattern);
273 }
274 }
275 }
276
277 #[test]
278 fn test02() {
279 let text="hello こんにちは world 世界";
280 let pattern = "こんにちは";
281
282 let ctr = kmpm_str(text, pattern).unwrap();
283 assert!(ctr==6);
284 }
285
286 #[test]
287 fn test03(){
288 let text="hello こんにちは world 世界";
289 let pattern = "2024";
290
291 assert!(kmpm_str(text, pattern).is_none());
292 }
293
294 #[test]
295 fn test04(){
296 let text="abababa";
297 let pattern = "aba";
298 println!("{:?}",kmpm_str_all(text, pattern));
299 }
300
301 #[test]
302 fn test05(){
303 let text="abababa";
304 let pattern = "aba";
305 println!("{:?}",kmpm_str_nad(text, pattern,0));println!("{:?}",kmpm_str_nad(text, pattern,1));}
308}