Several common string matching algorithms in JS

Here are examples of implementing several common string matching algorithms in JavaScript:

1. Simple string matching (brute force matching algorithm):

function bruteForceStringMatch(text, pattern) {
  const n = text.length;
  const m = pattern.length;

  for (let i = 0; i <= n - m; i++) {
    let j;
    for (j = 0; j < m; j++) {
      if (text[i + j] !== pattern[j]) {
        break;
      }
    }
    if (j === m) {
      return i;
    }
  }

  return -1;
}

const text = "Hello, world!";
const pattern = "world";
console.log(bruteForceStringMatch(text, pattern)); // 输出:7

2. Knuth-Morris-Pratt (KMP) algorithm:

function computeLPSArray(pattern) {
  const m = pattern.length;
  const lps = Array(m).fill(0);

  let len = 0;
  let i = 1;
  while (i < m) {
    if (pattern[i] === pattern[len]) {
      len++;
      lps[i] = len;
      i++;
    } else {
      if (len !== 0) {
        len = lps[len - 1];
      } else {
        lps[i] = 0;
        i++;
      }
    }
  }

  return lps;
}

function KMPSearch(text, pattern) {
  const n = text.length;
  const m = pattern.length;

  const lps = computeLPSArray(pattern);

  let i = 0;
  let j = 0;
  while (i < n) {
    if (pattern[j] === text[i]) {
      i++;
      j++;
    }

    if (j === m) {
      return i - j;
    } else if (i < n && pattern[j] !== text[i]) {
      if (j !== 0) {
        j = lps[j - 1];
      } else {
        i++;
      }
    }
  }

  return -1;
}

const text = "Hello, world!";
const pattern = "world";
console.log(KMPSearch(text, pattern)); // 输出:7

3. Boyer-Moore algorithm:

function buildBadCharTable(pattern) {
  const table = {};

  for (let i = 0; i < pattern.length; i++) {
    table[pattern[i]] = pattern.length - 1 - i;
  }

  return table;
}

function BMStringMatch(text, pattern) {
  const n = text.length;
  const m = pattern.length;
  const badCharTable = buildBadCharTable(pattern);

  let i = m - 1;
  while (i < n) {
    let j = m - 1;
    while (j >= 0 && pattern[j] === text[i]) {
      j--;
      i--;
    }

    if (j === -1) {
      return i + 1;
    }

    i += Math.max(badCharTable[text[i]] || m, 1);
  }

  return -1;
}

const text = "Hello, world!";
const pattern = "world";
console.log(BMStringMatch(text, pattern)); // 输出:7

4. Rabin-Karp algorithm:

Here is a sample code for the Rabin-Karp algorithm in JavaScript:

const prime = 101; // 选取一个质数作为进制

function RabinKarpSearch(text, pattern) {
  const n = text.length;
  const m = pattern.length;

  const patternHash = hash(pattern, m);
  let textHash = hash(text, m);

  for (let i = 0; i <= n - m; i++) {
    if (textHash === patternHash && checkEqual(text, i, pattern, 0, m)) {
      return i;
    }

    if (i < n - m) {
      textHash = recalculateHash(text, i, i + m, textHash, m);
    }
  }

  return -1;
}

function hash(str, len) {
  let hashValue = 0;
  for (let i = 0; i < len; i++) {
    hashValue += str.charCodeAt(i) * Math.pow(prime, i);
  }
  return hashValue;
}

function recalculateHash(str, oldIndex, newIndex, oldHash, len) {
  let newHash = oldHash - str.charCodeAt(oldIndex);
  newHash = newHash / prime;
  newHash += str.charCodeAt(newIndex) * Math.pow(prime, len - 1);
  return newHash;
}

function checkEqual(str1, start1, str2, start2, len) {
  for (let i = 0; i < len; i++) {
    if (str1[start1 + i] !== str2[start2 + i]) {
      return false;
    }
  }
  return true;
}

const text = "Hello, world!";
const pattern = "world";
console.log(RabinKarpSearch(text, pattern)); // 输出:7

The Rabin-Karp algorithm uses a hash function to calculate the hash value of the pattern string and the text string, and then slides the pattern string on the text string to match. If the hashes match, a further check is made to see if the pattern and text strings match exactly. This can reduce the number of string comparisons and improve the efficiency of the algorithm. The time complexity of the Rabin-Karp algorithm can reach O(n+m), where n is the text length and m is the pattern length.


 

Guess you like

Origin blog.csdn.net/weixin_39273589/article/details/132539285