github地址: https://github.com/Tiger-eat-cat/search.ts
export const createLongPrefix = (str: string): string[] => {
const prefixCollection: string[] = []
const length: number = str.length
if (length === 1) {
return prefixCollection
}
for (let i = 0; i < length - 1; i++) {
prefixCollection.push(str.slice(0, i + 1))
}
return prefixCollection
}
export const createLongSuffix = (str: string): string[] => {
const suffixCollection: string[] = []
const length: number = str.length
if (length === 1) {
return suffixCollection
}
for (let i = length - 1; i > 0; i--) {
suffixCollection.unshift(str.slice(i, length))
}
return suffixCollection
}
export const intersectionLength = (arg1: string[], arg2: string[]): number => {
let result = ''
const arrayMap: Map<string, string> = new Map()
arg1.forEach(item => arrayMap.set(item, item))
for (let i = 0; i < arg2.length; i++) {
const item = arg2[i]
if (arrayMap.has(item)) {
result = item
break
}
}
return result.length
}
export const buildKMPSearch = (search: string): Search => {
const partMatchTable: Map<number, number> = new Map() // pmt
for (let i = 0; i < search.length; i++) {
const str = search.slice(0, i + 1)
partMatchTable.set(i, intersectionLength(createLongSuffix(str), createLongPrefix(str)))
}
return {
search: (content: string): SearchResult[] => {
// debugger
const contentLength = content.length
const matchLength = search.length
const result: SearchResult[] = []
let i = 0
let j = 0
const calculateMatchIndex = (currentIndex: number): void => {
// debugger
j = j - (currentIndex - (partMatchTable.get(currentIndex - 1) as number))
}
const startMatch = () => {
// debugger
if (i < contentLength) {
if (content[i] !== search[j]) {
if (j !== 0) {
calculateMatchIndex(j)
} else {
i++
}
} else {
if (j === matchLength - 1) {
result.push({ start: i - (matchLength - 1), end: i })
i++
j = 0
} else {
i++
j++
}
}
startMatch()
}
}
startMatch()
return result
}
}
}