From d84549a82764b924c2c6ec3579b6b44c78c03f92 Mon Sep 17 00:00:00 2001 From: aladin002dz Date: 2023年10月19日 10:32:49 +0100 Subject: [PATCH] =?UTF-8?q?Knuth=E2=80=93Morris=E2=80=93Pratt=20algorithm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bit-Manipulation/BinaryCountSetBits.js | 2 +- Maths/AutomorphicNumber.js | 2 +- Maths/test/AutomorphicNumber.test.js | 16 ++++---- Project-Euler/Problem006.js | 6 +-- Search/InterpolationSearch.js | 2 +- Search/KMP.js | 57 ++++++++++++++++++++++++++ Search/test/KMP.test.js | 27 ++++++++++++ 7 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 Search/KMP.js create mode 100644 Search/test/KMP.test.js diff --git a/Bit-Manipulation/BinaryCountSetBits.js b/Bit-Manipulation/BinaryCountSetBits.js index b879f3bd67..b959caf062 100644 --- a/Bit-Manipulation/BinaryCountSetBits.js +++ b/Bit-Manipulation/BinaryCountSetBits.js @@ -16,7 +16,7 @@ function BinaryCountSetBits(a) { let count = 0 while (a) { - a &= (a - 1) + a &= a - 1 count++ } diff --git a/Maths/AutomorphicNumber.js b/Maths/AutomorphicNumber.js index d1b6608316..ba008271fc 100644 --- a/Maths/AutomorphicNumber.js +++ b/Maths/AutomorphicNumber.js @@ -35,6 +35,6 @@ export const isAutomorphic = (n) => { n = Math.floor(n / 10) n_sq = Math.floor(n_sq / 10) } - + return true } diff --git a/Maths/test/AutomorphicNumber.test.js b/Maths/test/AutomorphicNumber.test.js index 19b963388c..57f40d27ee 100644 --- a/Maths/test/AutomorphicNumber.test.js +++ b/Maths/test/AutomorphicNumber.test.js @@ -9,19 +9,19 @@ describe('AutomorphicNumber', () => { }) test.each([ - { n: -3 , expected: false }, - { n: -25 , expected: false }, + { n: -3, expected: false }, + { n: -25, expected: false } ])('should return false when n is negetive', ({ n, expected }) => { expect(isAutomorphic(n)).toBe(false) }) test.each([ - { n: 7 , expected: false }, - { n: 83 , expected: false }, - { n: 0 , expected: true }, - { n: 1 , expected: true }, - { n: 376 , expected: true }, - { n: 90625 , expected: true }, + { n: 7, expected: false }, + { n: 83, expected: false }, + { n: 0, expected: true }, + { n: 1, expected: true }, + { n: 376, expected: true }, + { n: 90625, expected: true } ])('should return $expected when n is $n', ({ n, expected }) => { expect(isAutomorphic(n)).toBe(expected) }) diff --git a/Project-Euler/Problem006.js b/Project-Euler/Problem006.js index 474de2ae96..804b165558 100644 --- a/Project-Euler/Problem006.js +++ b/Project-Euler/Problem006.js @@ -1,8 +1,8 @@ // https://projecteuler.net/problem=6 export const squareDifference = (num = 100) => { - let sumOfSquares = (num)*(num+1)*(2*num+1)/6 - let sums = (num*(num+1))/2 - + let sumOfSquares = (num * (num + 1) * (2 * num + 1)) / 6 + let sums = (num * (num + 1)) / 2 + return sums ** 2 - sumOfSquares // difference of square of the total sum and sum of squares } diff --git a/Search/InterpolationSearch.js b/Search/InterpolationSearch.js index e6deae496f..93f3b78b0e 100644 --- a/Search/InterpolationSearch.js +++ b/Search/InterpolationSearch.js @@ -36,4 +36,4 @@ export function interpolationSearch(arr, key) { } return -1 -} \ No newline at end of file +} diff --git a/Search/KMP.js b/Search/KMP.js new file mode 100644 index 0000000000..50c389c08d --- /dev/null +++ b/Search/KMP.js @@ -0,0 +1,57 @@ +/* + * Implements the Knuth-Morris-Pratt (KMP) algorithm for pattern searching. + * + * The KMP algorithm is a string searching algorithm that utilizes the concept of prefix tables or failure functions + * to efficiently match patterns in strings. It avoids unnecessary comparisons by taking advantage of the information + * gained from previous comparisons. + * + * This implementation constructs a prefix table that stores the longest proper prefix that is also a suffix for each + * prefix of the pattern. This table is then used to guide the pattern matching process, skipping over characters that + * are known to not match. + * + * The algorithm returns the starting index of the first occurrence of the pattern in the text. If the pattern is not + * found, the algorithm returns -1. + * + * Reference: https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm + */ + +function KMPSearch(text, pattern) { + let lps = new Array(pattern.length).fill(0) + computeLPS(pattern, lps) + let i = 0 + let j = 0 + while (i < text.length) { + if (pattern[j] == text[i]) { + j++ + i++ + } + if (j == pattern.length) { + return i - j + } else if (i < text.length && pattern[j] != text[i]) { + if (j != 0) j = lps[j - 1] + else i = i + 1 + } + } + return -1 +} + +function computeLPS(pattern, lps) { + let len = 0 + let i = 1 + while (i < pattern.length) { + if (pattern[i] == pattern[len]) { + len++ + lps[i] = len + i++ + } else { + if (len != 0) { + len = lps[len - 1] + } else { + lps[i] = 0 + i++ + } + } + } +} + +export { KMPSearch } diff --git a/Search/test/KMP.test.js b/Search/test/KMP.test.js new file mode 100644 index 0000000000..248a950f54 --- /dev/null +++ b/Search/test/KMP.test.js @@ -0,0 +1,27 @@ +import { KMPSearch } from '../KMP' + +describe('Rabin-Karp Search', function () { + test('KMP algorithm test 1', () => { + let text = 'AAAAA' + let pattern = 'AAA' + expect(KMPSearch(text, pattern)).toBe(0) + }) + + test('KMP algorithm test 2', () => { + let text = 'ABABDABACDABABCABAB' + let pattern = 'DABA' + expect(KMPSearch(text, pattern)).toBe(4) + }) + + test('KMP algorithm test 3', () => { + let text = 'ABABDABACDABABCABAB' + let pattern = 'ABABCABAB' + expect(KMPSearch(text, pattern)).toBe(10) + }) + + test('KMP algorithm test 4', () => { + let text = 'ABABDABACDABABCABAB' + let pattern = 'XYZ' + expect(KMPSearch(text, pattern)).toBe(-1) + }) +})

AltStyle によって変換されたページ (->オリジナル) /