HERE IS A SIMPLE EXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
接下來的步驟就都和上述的一樣了。完整過程如下:
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
HERE IS A SIMPLE EXAMPLE, WHICH CONTAINS MULTIPLE EXAMPLES. SIXLEE IS A WRONG WORD. EXAMPLEEXAMPLE
EXAMPLE
/// Boyer-Moore-MagicLen演算法(正向)。
pub fn boyer_moore_magiclen(text: &[char], pattern: &[char]) -> Vec<usize> {
let text_len = text.len();
let pattern_len = pattern.len();
if text_len == 0 || pattern_len == 0 || text_len < pattern_len {
return vec![];
}
let pattern_len_dec = pattern_len - 1;
let pattern_len_inc = pattern_len + 1;
let mut bad_char_shift_map: HashMap<char, usize> = HashMap::with_capacity(pattern_len_dec);
for (i, c) in pattern.iter().copied().take(pattern_len_dec).enumerate() {
bad_char_shift_map.insert(c, pattern_len_dec - i);
}
let last_pattern_char = pattern[pattern_len_dec];
let mut shift = 0;
let end_index = text_len - pattern_len;
let mut result = vec![];
'outer: loop {
for (i, pc) in pattern.iter().copied().enumerate().rev() {
if text[shift + i] != pc {
let p = shift + pattern_len;
if p == text_len {
break 'outer;
}
shift += bad_char_shift_map.get(&text[shift + pattern_len_dec]).copied().unwrap_or(pattern_len).max(
{
let c = text[p];
if c == last_pattern_char {
1
} else {
bad_char_shift_map.get(&c).map(|&c| c + 1).unwrap_or(pattern_len_inc)
}
}
);
if shift > end_index {
break 'outer;
}
continue 'outer;
}
}
result.push(shift);
if shift == end_index {
break;
}
shift += bad_char_shift_map.get(&text[shift + pattern_len_dec]).copied().unwrap_or(pattern_len).max(
{
let c = text[shift + pattern_len];
if c == last_pattern_char {
1
} else {
bad_char_shift_map.get(&c).map(|&c| c + 1).unwrap_or(pattern_len_inc)
}
}
);
if shift > end_index {
break;
}
}
result
}
/// Boyer-Moore-MagicLen演算法(反向)。
pub fn boyer_moore_magiclen_rev(text: &[char], pattern: &[char]) -> Vec<usize> {
let text_len = text.len();
let pattern_len = pattern.len();
if text_len == 0 || pattern_len == 0 || text_len < pattern_len {
return vec![];
}
let pattern_len_dec = pattern_len - 1;
let pattern_len_inc = pattern_len + 1;
let mut bad_char_shift_map: HashMap<char, usize> = HashMap::with_capacity(pattern_len_dec);
for (i, c) in pattern.iter().copied().enumerate().rev().take(pattern_len_dec) {
bad_char_shift_map.insert(c, i);
}
let first_pattern_char = pattern[0];
let mut shift = text_len - 1;
let start_index = pattern_len_dec;
let mut result = vec![];
'outer: loop {
for (i, pc) in pattern.iter().copied().enumerate() {
if text[shift - pattern_len_dec + i] != pc {
if shift < pattern_len {
break 'outer;
}
shift -= bad_char_shift_map.get(&text[shift - pattern_len_dec]).copied().unwrap_or(pattern_len).max(
{
let c = text[shift - pattern_len];
if c == first_pattern_char {
1
} else {
bad_char_shift_map.get(&c).map(|&c| c + 1).unwrap_or(pattern_len_inc)
}
}
);
if shift < start_index {
break 'outer;
}
continue 'outer;
}
}
result.push(shift - pattern_len_dec);
if shift == start_index {
break;
}
let s = bad_char_shift_map.get(&text[shift - pattern_len_dec]).copied().unwrap_or(pattern_len).max(
{
let c = text[shift - pattern_len];
if c == first_pattern_char {
1
} else {
bad_char_shift_map.get(&c).map(|&c| c + 1).unwrap_or(pattern_len_inc)
}
}
);
if shift < s {
break;
}
shift -= s;
if shift < start_index {
break;
}
}
result
}
/**
* Boyer-Moore-MagicLen演算法(正向)。
*/
public static Integer[] boyerMooreMagicLen(final char[] text, final char[] pattern) {
int textLength = text.length;
int patternLength = pattern.length;
if (textLength == 0 || patternLength == 0 || textLength < patternLength) {
return new Integer[0];
}
final int patternLengthDec = patternLength - 1;
final HashMap<Character, Integer> badCharShiftMap = new HashMap<>(patternLengthDec);
for (int i = 0; i < patternLengthDec; ++i) {
badCharShiftMap.put(pattern[i], patternLengthDec - i);
}
final char lastPatternChar = pattern[patternLengthDec];
int shift = 0;
final int endIndex = textLength - patternLength;
final ArrayList<Integer> result = new ArrayList<>();
outer:
while (true) {
for (int i = patternLengthDec; i >= 0; --i) {
if (text[shift + i] != pattern[i]) {
final int p = shift + patternLength;
if (p == textLength) {
break outer;
}
final int s1 = badCharShiftMap.getOrDefault(text[shift + patternLengthDec], patternLength);
final char c = text[p];
final int s2 = c == lastPatternChar ? 1 : (badCharShiftMap.getOrDefault(c, patternLength) + 1);
shift += Math.max(s1, s2);
if (shift > endIndex) {
break outer;
}
continue outer;
}
}
result.add(shift);
if (shift == endIndex) {
break;
}
final int s1 = badCharShiftMap.getOrDefault(text[shift + patternLengthDec], patternLength);
final char c = text[shift + patternLength];
final int s2 = c == lastPatternChar ? 1 : (badCharShiftMap.getOrDefault(c, patternLength) + 1);
shift += Math.max(s1, s2);
if (shift > endIndex) {
break;
}
}
return result.toArray(new Integer[result.size()]);
}
/**
* Boyer-Moore-MagicLen演算法(反向)。
*/
public static Integer[] boyerMooreMagicLenRev(final char[] text, final char[] pattern) {
int textLength = text.length;
int patternLength = pattern.length;
if (textLength == 0 || patternLength == 0 || textLength < patternLength) {
return new Integer[0];
}
final int patternLengthDec = patternLength - 1;
final HashMap<Character, Integer> badCharShiftMap = new HashMap<>(patternLengthDec);
for (int i = patternLengthDec; i >= 1; --i) {
badCharShiftMap.put(pattern[i], i);
}
final char firstPatternChar = pattern[0];
int shift = textLength - 1;
final int startIndex = patternLengthDec;
final ArrayList<Integer> result = new ArrayList<>();
outer:
while (true) {
for (int i = 0; i < patternLength; ++i) {
if (text[shift - patternLengthDec + i] != pattern[i]) {
final int p = shift - patternLength;
if (p < 0) {
break outer;
}
final int s1 = badCharShiftMap.getOrDefault(text[shift - patternLengthDec], patternLength);
final char c = text[p];
final int s2 = c == firstPatternChar ? 1 : (badCharShiftMap.getOrDefault(c, patternLength) + 1);
shift -= Math.max(s1, s2);
if (shift < startIndex) {
break outer;
}
continue outer;
}
}
result.add(shift - patternLengthDec);
if (shift == startIndex) {
break;
}
final int s1 = badCharShiftMap.getOrDefault(text[shift - patternLengthDec], patternLength);
final char c = text[shift - patternLength];
final int s2 = c == firstPatternChar ? 1 : (badCharShiftMap.getOrDefault(c, patternLength) + 1);
shift -= Math.max(s1, s2);
if (shift < startIndex) {
break;
}
}
return result.toArray(new Integer[result.size()]);
}
/**
* Boyer-Moore-MagicLen演算法(正向)。
*/
function boyerMooreMagicLen(text: string, pattern: string) {
const textLength = text.length;
const patternLength = pattern.length;
if (textLength === 0 || patternLength === 0 || textLength < patternLength) {
return [];
}
const patternLengthDec = patternLength - 1;
const badCharShiftMap: Record<string, number> = {};
for (let i = 0;i < patternLengthDec;++i) {
badCharShiftMap[pattern[i]] = patternLengthDec - i;
}
const lastPatternChar = pattern[patternLengthDec];
let shift = 0;
const endIndex = textLength - patternLength;
const result = [];
outer:
for (; ;) {
for (let i = patternLengthDec;i >= 0;i--) {
if (text[shift + i] !== pattern[i]) {
const p = shift + patternLength;
if (p === textLength) {
break outer;
}
let s1 = badCharShiftMap[text[shift + patternLengthDec]];
if (typeof s1 === "undefined") {
s1 = patternLength;
}
const c = text[p];
let s2;
if (c === lastPatternChar) {
s2 = 1;
} else {
s2 = badCharShiftMap[c];
if (typeof s2 === "undefined") {
s2 = patternLength + 1;
} else {
s2 += 1;
}
}
shift += Math.max(s1, s2);
if (shift > endIndex) {
break outer;
}
continue outer;
}
}
result.push(shift);
if (shift === endIndex) {
break;
}
let s1 = badCharShiftMap[text[shift + patternLengthDec]];
if (typeof s1 === "undefined") {
s1 = patternLength;
}
const c = text[shift + patternLength];
let s2;
if (c === lastPatternChar) {
s2 = 1;
} else {
s2 = badCharShiftMap[c];
if (typeof s2 === "undefined") {
s2 = patternLength + 1;
} else {
s2 + 1;
}
}
shift += Math.max(s1, s2);
if (shift > endIndex) {
break;
}
}
return result;
}
/**
* Boyer-Moore-MagicLen演算法(反向)。
*/
function boyerMooreMagicLenRev(text: string, pattern: string) {
const textLength = text.length;
const patternLength = pattern.length;
if (textLength === 0 || patternLength === 0 || textLength < patternLength) {
return [];
}
const patternLengthDec = patternLength - 1;
const badCharShiftMap: Record<string, number> = {};
for (let i = patternLengthDec;i >= 1;i--) {
badCharShiftMap[pattern[i]] = i;
}
const firstPatternChar = pattern[0];
let shift = textLength - 1;
const startIndex = patternLengthDec;
const result = [];
outer:
for (; ;) {
for (let i = 0;i < patternLength;++i) {
if (text[shift - patternLengthDec + i] !== pattern[i]) {
const p = shift - patternLength;
if (p < 0) {
break outer;
}
let s1 = badCharShiftMap[text[shift - patternLengthDec]];
if (typeof s1 === "undefined") {
s1 = patternLength;
}
const c = text[p];
let s2;
if (c === firstPatternChar) {
s2 = 1;
} else {
s2 = badCharShiftMap[c];
if (typeof s2 === "undefined") {
s2 = patternLength + 1;
} else {
s2 += 1;
}
}
shift -= Math.max(s1, s2);
if (shift < startIndex) {
break outer;
}
continue outer;
}
}
result.push(shift - patternLengthDec);
if (shift === startIndex) {
break;
}
let s1 = badCharShiftMap[text[shift - patternLengthDec]];
if (typeof s1 === "undefined") {
s1 = patternLength;
}
const c = text[shift - patternLength];
let s2;
if (c === firstPatternChar) {
s2 = 1;
} else {
s2 = badCharShiftMap[c];
if (typeof s2 === "undefined") {
s2 = patternLength + 1;
} else {
s2 += 1;
}
}
shift -= Math.max(s1, s2);
if (shift < startIndex) {
break;
}
}
return result;
}
// Boyer-Moore-MagicLen演算法(正向)。
func BoyerMooreMagicLen(text []rune, pattern []rune) []int {
textLength := len(text)
patternLength := len(pattern)
if textLength == 0 || patternLength == 0 || textLength < patternLength {
return make([]int, 0)
}
patternLengthDec := patternLength - 1
badCharShiftMap := make(map[rune]int)
for i := 0; i < patternLengthDec; i += 1 {
badCharShiftMap[pattern[i]] = patternLengthDec - i
}
lastPatternChar := pattern[patternLengthDec]
shift := 0
endIndex := textLength - patternLength
var result = make([]int, 0)
outer:
for {
for i := patternLengthDec; i >= 0; i -= 1 {
if text[shift+i] != pattern[i] {
p := shift + patternLength
if p == textLength {
break outer
}
s1, ok := badCharShiftMap[text[shift+patternLengthDec]]
if !ok {
s1 = patternLength
}
c := text[p]
var s2 int
if c == lastPatternChar {
s2 = 1
} else {
s2, ok = badCharShiftMap[c]
if ok {
s2 += 1
} else {
s2 = patternLength + 1
}
}
if s1 > s2 {
shift += s1
} else {
shift += s2
}
if shift > endIndex {
break outer
}
continue outer
}
}
result = append(result, shift)
if shift == endIndex {
break
}
s1, ok := badCharShiftMap[text[shift+patternLengthDec]]
if !ok {
s1 = patternLength
}
c := text[shift+patternLength]
var s2 int
if c == lastPatternChar {
s2 = 1
} else {
s2, ok = badCharShiftMap[c]
if ok {
s2 += 1
} else {
s2 = patternLength + 1
}
}
if s1 > s2 {
shift += s1
} else {
shift += s2
}
if shift > endIndex {
break
}
}
return result
}
// Boyer-Moore-MagicLen演算法(反向)。
func BoyerMooreMagicLenRev(text []rune, pattern []rune) []int {
textLength := len(text)
patternLength := len(pattern)
if textLength == 0 || patternLength == 0 || textLength < patternLength {
return make([]int, 0)
}
patternLengthDec := patternLength - 1
badCharShiftMap := make(map[rune]int)
for i := patternLengthDec; i >= 1; i -= 1 {
badCharShiftMap[pattern[i]] = i
}
firstPatternChar := pattern[0]
shift := textLength - 1
startIndex := patternLengthDec
var result = make([]int, 0)
outer:
for {
for i := 0; i < patternLength; i += 1 {
if text[shift-patternLengthDec+i] != pattern[i] {
p := shift - patternLength
if p < 0 {
break outer
}
s1, ok := badCharShiftMap[text[shift-patternLengthDec]]
if !ok {
s1 = patternLength
}
c := text[p]
var s2 int
if c == firstPatternChar {
s2 = 1
} else {
s2, ok = badCharShiftMap[c]
if ok {
s2 += 1
} else {
s2 = patternLength + 1
}
}
if s1 > s2 {
shift -= s1
} else {
shift -= s2
}
if shift < startIndex {
break outer
}
continue outer
}
}
result = append(result, shift-patternLengthDec)
if shift == startIndex {
break
}
s1, ok := badCharShiftMap[text[shift-patternLengthDec]]
if !ok {
s1 = patternLength
}
c := text[shift-patternLength]
var s2 int
if c == firstPatternChar {
s2 = 1
} else {
s2, ok = badCharShiftMap[c]
if ok {
s2 += 1
} else {
s2 = patternLength + 1
}
}
if s1 > s2 {
shift -= s1
} else {
shift -= s2
}
if shift < startIndex {
break
}
}
return result
}