Skip to content

Instantly share code, notes, and snippets.

@db48x
Created March 16, 2012 07:35
Show Gist options
  • Save db48x/2049012 to your computer and use it in GitHub Desktop.
Save db48x/2049012 to your computer and use it in GitHub Desktop.
implement KMP for substring iterator
// uses KMP
fn iter_matches(s:str, sep:str, count:option<uint>, f:fn(uint, uint)) {
let mut table = [-1, 0],
calls = 0u;
let mut pos = 0u, candidate = 0,
sep_len = str::len(sep);
while (pos < sep_len) {
if pos < 2u { pos += 1u; }
else if sep[pos - 1u] == sep[candidate] {
candidate += 1;
table += [candidate];
pos += 1u;
}
else if candidate > 0 {
candidate = table[candidate];
}
else {
table += [0];
pos += 1u;
}
}
let mut pos = 0u, match = 0u,
len = str::len(s);
while (pos + match < len &&
alt count { some(c) { calls < c } none { true } }) {
if (sep[pos] == s[match + pos]) {
if (pos == sep_len - 1u) {
f(match, match + pos + 1u);
calls += 1u;
match += pos + 1u;
pos = 0u;
} else {
pos += 1u;
}
} else {
match = (match as int + pos as int - table[pos]) as uint;
pos = if (table[pos] > -1) { table[pos] as uint }
else { 0u };
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment