You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

字符串相似度计算算法问题求助:while循环逻辑异常排查

字符串相似度计算中连续匹配长度错误的问题排查

你的问题出在while循环的终止条件逻辑完全写反,同时缺少边界检查,导致提前终止了连续匹配的计数。

具体问题分析

当i=3、j=2时:

  • str1[3] = 'n',str2[2] = 'n',触发匹配逻辑,p初始化为0
  • 第一次进入while循环:str1[3+0] == str2[2+0] 成立,p自增为1
  • 此时判断(i+p < n) || (j+p < str2.length()):i+p=4 <9(str1长度)为true,直接触发break跳出循环,所以p最终是1,和预期的2不符。

这个判断条件的逻辑完全搞反了:你本来想在超出字符串长度时停止,但现在写成了只要还没超出就停止,直接打断了后续的匹配计数。另外,当前代码还存在数组越界风险——如果i+p或j+p超出字符串长度,调用charAt会抛出IndexOutOfBoundsException。

修复后的代码

import java.util.ArrayList;
import java.util.Collections;

public class StringSimilarity {
    public static void compareStringToString(String str1, String str2) {
        ArrayList<Integer> numSames = new ArrayList<>();
        int p = 0, n;

        if (str1.length() >= str2.length()) {
            n = str1.length();
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < str2.length(); j++) {
                    if (str1.charAt(i) == str2.charAt(j)) {
                        p = 0;
                        // 先检查边界再比较字符,避免越界,同时正确计数连续匹配
                        while (i + p < str1.length() && j + p < str2.length() 
                               && str1.charAt(i + p) == str2.charAt(j + p)) {
                            p++;
                        }
                        numSames.add(p);
                    }
                }
            }
        } else {
            n = str2.length();
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < str1.length(); j++) {
                    if (str2.charAt(i) == str1.charAt(j)) {
                        p = 0;
                        while (i + p < str2.length() && j + p < str1.length() 
                               && str2.charAt(i + p) == str1.charAt(j + p)) {
                            p++;
                        }
                        numSames.add(p);
                    }
                }
            }
        }

        // 处理无匹配的情况,避免空列表调用max报错
        if (numSames.isEmpty()) {
            System.out.println("两个字符串的相似度为: 0%");
        } else {
            float similarity = ((float) Collections.max(numSames) / n) * 100;
            System.out.println("两个字符串的相似度为: " + similarity + "%");
        }
    }
}

修复说明

  1. 修正循环逻辑:把while循环的判断改为先检查i+p和j+p是否在各自字符串的长度范围内,再比较字符,既避免数组越界,又能正确计数连续匹配的长度。
  2. 移除错误break:删掉原来逻辑颠倒的break语句,让循环自然终止于边界或字符不匹配的情况。
  3. 增加空列表判断:避免两个字符串完全不匹配时,调用Collections.max抛出异常。
  4. 补全else分支:完善了原代码中未实现的短串在前的处理逻辑。

现在测试i=3、j=2的场景:

  • p初始为0,进入循环:str1[3] == str2[2]('n' == 'n'),p变为1
  • 再次检查:i+p=4 <9且j+p=3 <7,str1[4] == str2[3]('s' == 's'),p变为2
  • 再次检查:i+p=5 <9且j+p=4 <7,str1[5]是'i',str2[4]是'c',不相等,循环终止,p=2,符合预期。

内容的提问来源于stack exchange,提问作者Hajime

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 04:54:23