【JAVA实现近义词匹配挖取算法】

JAVA实现近义词匹配挖取算法

Levenshtein类 用于实现挖词逻辑的核心,主要用于字符串匹配度计算,支持ABA词汇。

/**
 * 计算字符串之间匹配度算法
 */
public class Levenshtein {
    private int compare(String str, String target) {
        int d[][]; // 矩阵
        int n = str.length();
        int m = target.length();
        int i; // 遍历str的
        int j; // 遍历target的
        char ch1; // str的
        char ch2; // target的
        int temp; // 记录相同字符,在某个矩阵位置值的增量,不是0就是1

        if (n == 0) {
            return m;
        }

        if (m == 0) {
            return n;
        }

        d = new int[n + 1][m + 1];

        for (i = 0; i <= n; i++) { // 初始化第一列
            d[i][0] = i;
        }

        for (j = 0; j <= m; j++) { // 初始化第一行
            d[0][j] = j;
        }

        for (i = 1; i <= n; i++) { // 遍历str
            ch1 = str.charAt(i - 1);
            // 去匹配target
            for (j = 1; j <= m; j++) {
                ch2 = target.charAt(j - 1);
                if (ch1 == ch2) {
                    temp = 0;
                } else {
                    temp = 1;
                }

                // 左边+1,上边+1, 左上角+temp取最小
                d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + temp);
            }
        }

        return d[n][m];
    }

    private int min(int one, int two, int three) {
        return (one = one < two ? one : two) < three ? one : three;
    }

    /**
     * 获取两字符串的相似度
     *
     * @param str
     * @param target
     *
     * @return
     */

    public float getSimilarityRatio(String str, String target) {
        return 1 - (float) compare(str, target) / Math.max(str.length(), target.length());
    }

实现算法代码

//实现算法
public static String getKeyWord(String keyWord, String userAnswer, Integer index) {
        Levenshtein levenshtein = new Levenshtein();
        String[] keyWordArr = keyWord.split("");
        String[] answerArr = userAnswer.split("");
        String begin = keyWordArr[index];
        int beginIndex = 0;
        //当前记录数
        int pitchIndex = 0;
        //命中暂时记录数
        int pitchAnswerIndex = 0;
        //间隔数
        int intervalIndex = 0;
        float percentage = 0;
        String result = "";
        String result2 = "";
        index++;
        Map<String, Integer> map = new HashMap<>();
        //设置字符可消费的数量
        for (int i = 0; i < keyWordArr.length; i++) {
            Integer num = map.get(keyWordArr[i]);
            if (null != num) {
                map.put(keyWordArr[i], num + 1);
            } else {
                map.put(keyWordArr[i], 1);
            }
        }
        for (int j = 0; j < answerArr.length; j++) {
            String answer = answerArr[j];
            if (begin.equals(answer)) {
                if (result.equals("")) {
                    result = answer;
                } else if (intervalIndex >= keyWord.length() * 0.2) {
                    result = answer;
                } else {
                    result = result + answer;
                }
                beginIndex = 1;
                pitchIndex++;
            } else {
                if (beginIndex == 1) {
                    //命中间隔判断,超过原词汇0.2未命中则视为失效,重新查找
                    if (intervalIndex >= keyWord.length() * 0.2) {
                        beginIndex = 0;
                        result = "";
                        result2 = "";
                        pitchIndex = 0;
                        pitchAnswerIndex = 0;
                        intervalIndex = 0;
                        continue;
                    }
                    //消费逻辑
                    Integer num = map.get(answer);
                    if (null != num && num > 0) {
                        map.put(answer, num - 1);
                        pitchIndex++;
                    } else {
                        intervalIndex++;
                    }
                    result = result + answer;
                    float percentage2 = levenshtein.getSimilarityRatio(result, keyWord);
                    //获取暂时满足条件的串
                    if (percentage2 >= percentage || pitchIndex > pitchAnswerIndex) {
                        result2 = result;
                        percentage = levenshtein.getSimilarityRatio(result2, keyWord);
                        pitchAnswerIndex = pitchIndex;
                        intervalIndex = 0;
                    }
                    if (intervalIndex >= keyWord.length() * 0.2 && pitchAnswerIndex > keyWord.length() * 0.6) {
                        break;
                    }
                }
            }
        }
        //返回满足百分之60以上的最优结果
        if (pitchAnswerIndex >= keyWord.length() * 0.6) {
            return result2;
        }
        //如不满足则重新查找
        if (index < keyWord.length()) {
            return getKeyWord(keyWord, userAnswer, index);
        } else {
            return null;
        }
    }

效果测试

 public static void main(String[] args) {
        String a = "甲构成故意杀人(预备)法律法条和过失致人死亡罪。";
        String b = "法律法规";
       String c = getKeyWordTest(b,a,0);
       System.out.println("取词结果为:" + c);
  }

结果展示
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值