字符串相似度计算算法问题求助: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 + "%"); } } }
修复说明
- 修正循环逻辑:把while循环的判断改为先检查
i+p和j+p是否在各自字符串的长度范围内,再比较字符,既避免数组越界,又能正确计数连续匹配的长度。 - 移除错误break:删掉原来逻辑颠倒的break语句,让循环自然终止于边界或字符不匹配的情况。
- 增加空列表判断:避免两个字符串完全不匹配时,调用
Collections.max抛出异常。 - 补全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
相关产品推荐
相关产品推荐

