zoukankan      html  css  js  c++  java
  • 计算字符串的相似度 结构之法 3

       我们的目的在于判断字符串的相似程度。我们定义了一套操作方法来把两个不同的字符串变得相同,具体的操作方法为:

    1、修改一个字符(如吧“a”替换为“b”);

    2、增加一个字符(如把“abdd”变为“aebdd”);

    3、删除一个字符(如把“travelling”变为“traveling”)。

    比如,对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的。上面的两种方案,都仅需要一次操作。把这个操作所需要的次数定义为两个字符串的距离,而相似程度等于“距离+1”的倒数。也就是说,“abcdefg”和“abcdef”的距离为1,相似度为1/2=0.5。

        给定任意两个字符串,写出一个算法来计算出他们的相似度:

            两个字符串的距离肯定不超过他们的长度之和(我们可以通过删除操作把两个串转化为空串)。虽然这个结论对结果没有帮助,但至少可以知道,任意两个字符串的距离都是有限的。

             考虑如何才能把这个问题转化成规模较小的同样的问题。

      1、删除A串中的第一个字符,然后计算A[2,....,lenA]和B[1,....,lenB]的距离。

      2、删除B串中的第一个字符,然后计算A[1,....,lenA]和B[2,....,lenB]的距离。

      3、修改A串的第一个字符为B串的第一个字符,然后计算A[2,....,lenA]和B[2,....,lenB]的距离。

      4、修改B串的第一个字符为A串的第一个字符,然后计算A[2,....,lenA]和B[2,....,lenB]的距离。

      5、增加B串的第一个字符到A串的第一个字符之前,然后计算A[1,....,lenA]和B[2,....,lenB]的距离。

      6、增加A串的第一个字符到B串的第一个字符之前,然后计算A[2,....,lenA]和B[1,....,lenB]的距离。

    在这个题目中,可以将上面6个操作合并为:

    1、一步操作之后,再将A[2,....,lenA]和B[1,....,lenB]变成相同字符串。

    2、一步操作之后,再将A[1,....,lenA]和B[2,....,lenB]变成相同字符串。

    3、一步操作之后,再将A[2,....,lenA]和B[2,....,lenB]变成相同字符串。

    #include<iostream>
    #include<string>
    #include<algorithm>
    using namespace std;

    int minValue(int a,int b,int c) //计算3个数中的最小值
    {
    int tmp=min(a,b);
    return min(tmp,c);
    }
    //计算两个字符串的距离
    //最好用动态规划的方法记录下各值,这样就可以避免重复计算的问题,动态规划算法有待进一步实现
    int CalculateStringDistance(string strA,int pABegin,int pAEnd, string strB,int pBBegin,int pBEnd)
    {
    if(pABegin>pAEnd)
    {
    if(pBBegin>pBEnd) return 0;
    else return pBEnd-pBBegin+1;
    }
    if(pBBegin>pBEnd)
    {
    if(pABegin>pAEnd) return 0;
    else return pAEnd-pABegin+1;
    }
    if(strA[pABegin]==strB[pBBegin])
    {
    return CalculateStringDistance(strA,pABegin+1,pAEnd,strB,pBBegin+1,pBEnd);
    }
    else
    {
    int t1=CalculateStringDistance(strA,pABegin+1,pAEnd,strB,pBBegin,pBEnd);
    int t2=CalculateStringDistance(strA,pABegin,pAEnd,strB,pBBegin+1,pBEnd);
    int t3=CalculateStringDistance(strA,pABegin+1,pAEnd,strB,pBBegin+1,pBEnd);
    return minValue(t1,t2,t3)+1;
    }
    }


    int main()
    {
    string str1,str2;
    cout<<"请输入两个字符串"<<endl;
    cin>>str1>>str2;
    int a,b;
    a=str1.size();
    b=str2.size();
    cout<<"a=="<<a<<endl;
    cout<<"b=="<<b<<endl;
    cout<<"两字符串的距离为:"<<CalculateStringDistance(str1,0,a,str2,0,b);
    return 0;
    }

    个人觉得这个跟算法中的求两个序列的最长公共子序列有点像。  

  • 相关阅读:
    Cronolog切割tomcat日志
    使用TortoiseGit+码云管理项目代码
    POI使用 (4.0) 常用改动
    MySQL-with rollup函数运用
    CentOS7使用yum安装MySQL8.0
    java 8 新特性之Stream的排序/分类
    java阳历转农历
    MyBatis SQL xml处理小于号与大于号
    mysql update不能直接使用select的结果
    Java面试中遇到的坑【填坑篇】
  • 原文地址:https://www.cnblogs.com/zdblog/p/3664902.html
Copyright © 2011-2022 走看看