21xrx.com
2024-11-10 00:52:04 Sunday
登录
文章检索 我的文章 写文章
如何用C++判断两个字符串的相似度:详解
2023-07-05 13:16:28 深夜i     --     --
C++ 字符串 相似度 判断 详解

我们在日常生活中常常需要比较两个字符串的相似程度,例如在进行拼写检查、文本分类、信息检索等任务时都需要用到这个技能。而在C++中,我们可以使用一些算法和数据结构来判断两个字符串的相似度。在本文中,我们将详细介绍如何用C++来判断两个字符串的相似程度。

1. 汉明距离算法(Hamming Distance Algorithm)

汉明距离算法是用于计算两个等长字符串之间的距离的一种算法。它的原理是通过对比这两个字符串在相同位置上的字符是否相同来确定它们的相似程度,字符不相同则距离加一。

C++代码实现:


int hamming_distance(string str1, string str2){

  if (str1.size() != str2.size()) return -1; // 两个字符串长度不相等

  int distance = 0;

  for (int i = 0; i < str1.size(); i++){

    distance += (str1[i] != str2[i]);

  }

  return distance;

}

2. 莱文斯坦距离算法(Levenshtein Distance Algorithm)

莱文斯坦距离算法也是用于计算两个字符串之间距离的一种算法。与汉明距离算法不同的是,莱文斯坦距离算法在比较时可以对字符串进行增加、删除和替换等操作,也就是说,两个字符串的长度可以不相等。

C++代码实现:


int levenshtein_distance(string str1, string str2){

  int len1 = str1.size(), len2 = str2.size();

  int dp[len1+1][len2+1];

  for (int i = 0; i <= len1; ++i) dp[i][0] = i;

  for (int i = 0; i <= len2; ++i) dp[0][i] = i;

  for (int i = 1; i <= len1; ++i) {

    for (int j = 1; j <= len2; ++j) {

      dp[i][j] = min(dp[i-1][j-1] + (str1[i-1] != str2[j-1]), \

            min(dp[i][j-1] + 1, dp[i-1][j] + 1));

    }

  }

  return dp[len1][len2];

}

3. Jaro-Winkler距离算法

Jaro-Winkler距离算法是一种用于计算两个字符串相似度的算法,它的原理类似于莱文斯坦距离算法,但有些许差别。Jaro-Winkler距离算法将两个字符串相似度分为两个部分,第一个部分是Jaro距离(Jaro Distance),第二个部分是Winkler增益(Winkler Boost)。Jaro距离用于衡量两个字符串的相似度,而Winkler增益主要用于区分两个字符串相似但是不完全相同的情况。

C++代码实现:


double jaro_winkler(string str1, string str2){

  int m = str1.size(), n = str2.size();

  if (m == 0 || n == 0) return 0; // 如果两个字符串中有任意一个为空,相似度为0

  int max_len = max(m, n) / 2 - 1;

  vector<bool> str1_visited(m, false);

  vector<bool> str2_visited(n, false);

  int common_chars = 0; // 统计两个字符串中相同的字符数量以及位于不同字符串中的相同字符的位置之和

  int transposition = 0; // 统计位于不同字符串中的相同字符的位置之和

  for (int i = 0; i < m; i++) {

    int start = max(0, i - max_len), end = min(i + max_len + 1, n);

    for (int j = start; j < end; j++) {

      if (str2_visited[j] || str1[i] != str2[j]) continue;

      str1_visited[i] = true;

      str2_visited[j] = true;

      common_chars++;

      break;

    }

  }

  if (common_chars == 0) return 0; // 如果两个字符串没有相同的字符,相似度为0

  int k = 0;

  for (int i = 0; i < m; i++) {

    if (!str1_visited[i]) continue;

    while (!str2_visited[k]) k++;

    if (str1[i] != str2[k]) transposition++;

    k++;

  }

  double jaro_distance = ((double) common_chars * 1.0 / m + (double) common_chars * 1.0 / n + (double) (common_chars - transposition / 2) * 1.0 / common_chars) / 3;

  double jaro_winkler_distance = jaro_distance + (1 - jaro_distance) * (min(3, (int) str1.size()) * 1.0 / 10);

  return jaro_winkler_distance;

}

总之,以上三种算法都可以有效地计算两个字符串的相似程度。根据实际应用场景来选择使用哪种算法可以更好地提高程序的准确性和效率。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复