Lucene4.3.1字符串距离接口StringDistance实现之LevensteinDistance源码解析

LevensteinDistance是LevenshteinDistance算法的实现,采用三个一维数组代替了一个二维数组,一个数组为上一轮计算的值,一个数组保存本轮计算的值,最后一个数组用于交换两个数组的值。

package org.apache.lucene.search.spell;


public final class LevensteinDistance implements StringDistance {


    public LevensteinDistance () {
    }

    @Override
    public float getDistance (String target, String other) {
      char[] sa;
      int n;
      int p[]; //上一行计算的值
      int d[]; //当前行计算的值
      int _d[]; //用于交换p和d
      
        

        sa = target.toCharArray();
        n = sa.length;
        p = new int[n+1]; 
        d = new int[n+1]; 
      
        final int m = other.length();
        if (n == 0 || m == 0) {
          if (n == m) {
            return 1;
          }
          else {
            return 0;
          }
        } 


        int i; // target的索引
        int j; // other的索引

        char t_j; //other的第j个字符

        int cost; 
		//初始化,将空字符串转换为长度为i的target字符串的操作次数
        for (i = 0; i<=n; i++) {
            p[i] = i;
        }
		
        for (j = 1; j<=m; j++) {
            t_j = other.charAt(j-1);
            //左方的初始值为将长度为j的other字符串转换为空字符串的操作次数
			d[0] = j;
			//计算将长度为i的target字符串转换为长度为j的other字符串的操作次数
            for (i=1; i<=n; i++) {
                cost = sa[i-1]==t_j ? 0 : 1;
				//d[i-1]左方、p[i]上方、p[i-1]左上
                d[i] = Math.min(Math.min(d[i-1]+1, p[i]+1),  p[i-1]+cost);
            }

            //交换p和d,用于下一轮计算
            _d = p;
            p = d;
            d = _d;
        }

		//计算相似度,p中最后一个元素为LevensteinDistance
        return 1.0f - ((float) p[n] / Math.max(other.length(), sa.length));
    }

  @Override
  public int hashCode() {
    return 163 * getClass().hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (null == obj) return false;
    return (getClass() == obj.getClass());
  }

  @Override
  public String toString() {
    return "levenstein";
  }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值