JS 中几种常见的字符串匹配算法

下面是在 JavaScript 中实现几种常见的字符串匹配算法的示例:

1. 简单的字符串匹配(暴力匹配算法):

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) 算法:

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 算法:

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 算法:

以下是 JavaScript 中的 Rabin-Karp 算法示例代码:

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

Rabin-Karp 算法使用了哈希函数来计算模式串和文本串的哈希值,然后在文本串上滑动模式串进行匹配。如果哈希值匹配,则进一步检查模式串和文本串是否完全匹配。这样可以减少字符串比较的次数,提高算法的效率。Rabin-Karp 算法的时间复杂度可以达到 O(n+m),其中 n 是文本长度,m 是模式长度。


 

猜你喜欢

转载自blog.csdn.net/weixin_39273589/article/details/132539285