Coderbyte Java Longest Word题目测试用例未通过问题咨询
LongestWord函数测试用例失败排查与修复
问题描述
按照需求实现的LongestWord(sen)函数,对基础示例的输出符合预期,但平台校验环节存在多个测试用例判定不通过,需定位代码逻辑缺陷并完成修复。
需求规则
- 函数接收非空字符串入参sen,返回字符串中长度最大的有效单词
- 若存在多个长度相同的最长单词,返回字符串中最先出现的那一个
- 解析过程中完全忽略所有标点符号
- 基础示例参考:
- 输入
"fun&!! time",输出time - 输入
"I love dogs",输出love
- 输入
未通过测试用例
- 输入
"a beautiful sentence^&!",预期输出beautiful - 输入
"oxford press",预期输出oxford - 输入
"123456789 98765432",预期输出123456789 - 输入
"a b c dee",预期输出dee - 输入
"a confusing /:sentence:/[ this is not!!!!!!!~",预期输出confusing
当前实现代码
import java.util.Arrays; import java.util.Comparator; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; class Main { public static final String REG_EXP_CHAR_ONLY = "(?=.*?[a-zA-Z0-9 ])"; public static String LongestWord(String sen) { StringBuffer strBuffer = new StringBuffer(); for (String c : sen.split("")) { if (isValid(c)) { strBuffer.append(c); } } String longest = Arrays.stream(strBuffer.toString().split(" ")).max(Comparator.comparingInt(String::length)) .orElse(null); return longest; } public static boolean isValid(String c) { Pattern pattern = Pattern.compile(REG_EXP_CHAR_ONLY); Matcher matcher = pattern.matcher(c); boolean matchFound = matcher.find(); if (matchFound) { return true; } return false; } public static void main (String[] args) { Scanner s = new Scanner(System.in); System.out.print(LongestWord(s.nextLine())); } }
根因定位
逐逻辑拆解后,所有测试失败的触发原因和实现代码的缺陷一一对应:
- 有效字符校验逻辑存在根本性缺陷
代码中定义的正则REG_EXP_CHAR_ONLY = "(?=.*?[a-zA-Z0-9 ])"是正向断言模式,作用是判断目标字符串中是否存在任意一个字母、数字或空格,而非校验当前逐字符遍历到的字符本身是否属于有效集合。逐字符匹配标点、符号时,该断言无法准确完成“剔除标点、保留有效内容”的目标,会出现字符误删、有效内容被过滤的问题,最终导致拼接后的单词长度计算出现偏差。 - 最长值选择规则和题目要求相悖
JDK流操作中的max()方法,在遇到相同长度的元素时,会保留序列中靠后位置的元素,和题目要求的“同长度下返回第一个出现的单词”规则完全冲突。比如输入"oxford press"时,两个单词长度均为6,当前代码会返回后出现的press,和预期的oxford不符。 - 空字符串干扰长度计算
经过缺陷逻辑过滤后的字符串,会因为连续被剔除的标点/符号生成连续空格,执行split(" ")切分时会生成多个长度为0的空字符串。这些空串会打乱原有单词的顺序和长度计算逻辑,比如输入带斜杠、方括号的复杂句子时,最终会错误返回标点残留的短词,而非预期的最长有效单词。 - 逐字符编译正则的效率与逻辑双重问题
代码每判断一个字符就重新编译一次正则表达式,不仅运行效率极低,还因为正则本身的逻辑缺陷,无法准确识别需要剔除的字符。比如输入纯数字串"123456789 98765432"时,因为字符校验逻辑错误,会误删前序数字内容,最终返回非预期的结果。
修复方向
- 替换有效字符判断逻辑:逐字符遍历入参时,仅保留大小写字母、数字、空格三类有效内容,其余标点、符号直接剔除,不再依赖存在逻辑缺陷的正向断言正则;判断标点时直接替换为空格分隔符,避免单词被无空格拼接后误判为长单词。
- 调整最长单词的选择逻辑:遍历切分后的有效单词列表,仅当遇到长度大于当前记录的最长单词时,才更新记录值,长度相等时不替换,保证保留最先出现的最长单词,替代不符合规则的
Stream.max()实现。 - 切分完成后过滤所有长度为0的空字符串,消除连续分隔符带来的计算干扰。
内容的提问来源于stack exchange,提问作者Banana Tech
相关产品推荐
相关产品推荐

