Java中使用字符串数组移除目标字符串元素时多元素匹配失效问题排查
问题排查与修复方案
我一眼就看出问题出在你的双层循环逻辑上啦!咱们来拆解一下:
你现在的逻辑是,遍历原句拆分后的每个单词,然后每一次和words里的元素不匹配时,就把这个单词追加到结果里。举个例子,比如第二个测试用例里的单词"The",words数组是["is", "Greece"]:
- 第一次和"is"不匹配,你把"The"加了一次;
- 第二次和"Greece"不匹配,你又把"The"加了一次;
这就导致结果里出现了两次"The",其他符合条件的单词也会重复多次,次数等于words数组中不匹配的元素数量。
正确的逻辑应该是:只有当当前单词和words数组里的所有元素都不匹配时,才把它加入结果。也就是说,我们需要先判断这个单词是否属于要删除的列表,不属于的话才追加。
修复后的代码实现
这里给你两种修复思路,选哪种都可以:
思路1:标记法(不依赖集合)
class Test { public static void main(String[] args) { WordDeleter wordDeleter = new WordDeleter(); // Hello System.out.println(wordDeleter.remove("Hello Java", new String[] { "Java" })); // The Athens in System.out.println(wordDeleter.remove("The Athens is in Greece", new String[] { "is", "Greece" })); // This cat System.out.println(wordDeleter.remove("This is cat", new String[] { "is" })); } } class WordDeleter { public String remove(String phrase, String[] words) { String[] arrayPhrase = phrase.split(" "); StringBuilder result = new StringBuilder(); // 用StringBuilder更高效,避免频繁字符串拼接 for (String word : arrayPhrase) { boolean shouldKeep = true; // 默认保留当前单词 for (String target : words) { if (word.equalsIgnoreCase(target)) { shouldKeep = false; // 找到匹配的,标记为不保留 break; // 不用继续遍历了 } } if (shouldKeep) { result.append(word).append(" "); } } return result.toString().trim(); } }
思路2:利用Set优化查找(更高效,尤其是words数组很大时)
把words数组转成一个忽略大小写的Set,这样判断单词是否需要删除会更快:
import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; class Test { public static void main(String[] args) { WordDeleter wordDeleter = new WordDeleter(); // Hello System.out.println(wordDeleter.remove("Hello Java", new String[] { "Java" })); // The Athens in System.out.println(wordDeleter.remove("The Athens is in Greece", new String[] { "is", "Greece" })); // This cat System.out.println(wordDeleter.remove("This is cat", new String[] { "is" })); } } class WordDeleter { public String remove(String phrase, String[] words) { // 转成忽略大小写的Set Set<String> wordSet = Arrays.stream(words) .map(String::toLowerCase) .collect(Collectors.toCollection(HashSet::new)); return Arrays.stream(phrase.split(" ")) .filter(word -> !wordSet.contains(word.toLowerCase())) .collect(Collectors.joining(" ")); } }
测试输出
修复后运行代码,输出就会符合预期:
Hello The Athens in This cat
另外提个小建议:尽量用StringBuilder来拼接字符串,而不是直接用+=,因为字符串是不可变的,每次+=都会创建新对象,性能会差很多,尤其是处理长文本的时候。
内容的提问来源于stack exchange,提问作者Orest Dymarchuk
相关产品推荐
相关产品推荐

