Java 如何从字符串中删除所有重复的单词,即使所有重复的单词都不保留? 样本输入 输出:

Java 如何从字符串中删除所有重复的单词,即使所有重复的单词都不保留? 样本输入 输出:,java,arrays,string,Java,Arrays,String,这是我试过的代码 public static void main(String[] args) throws Exception { String name = "Hello hi stackoverflow remain only Hello hi"; String ar[] = name.split("\\s"); ArrayList<String> dup = new ArrayList<String>();//duplicate words

这是我试过的代码

public static void main(String[] args) throws Exception {
    String name = "Hello hi stackoverflow remain only Hello hi";
    String ar[] = name.split("\\s");
    ArrayList<String> dup = new ArrayList<String>();//duplicate words
    ArrayList<String> res = new ArrayList<String>();
    for (int i = 0; i < ar.length; i++) {
        res.add(ar[i]);
        String del = ar[i];
        for (int j = i + 1; j < ar.length; j++) {
            if (ar[j].equals(dup)) {
                dup.add(del);
                break;
            }
        }
    }
}

for (int i = 0; i < dup.size(); i++) {
    for (int j = i + 1; j < res.size(); j++) {
        if (st[i].equals(st2[j])) {
            res.remove(res.IndexOf(j));
        }
    }
}
publicstaticvoidmain(字符串[]args)引发异常{
String name=“Hello hi stackoverflow仅保留Hello hi”;
字符串ar[]=name.split(\\s”);
ArrayList dup=新的ArrayList();//重复的单词
ArrayList res=新的ArrayList();
for(int i=0;i
如果您使用的是Java 8,您可以这样使用:

String text = "Hello hi hi stackoverflow remain only Hello ";
List<String> list = new ArrayList<>(Arrays.asList(text.split("\\s+")));
list.removeIf(element -> Collections.frequency(list, element) > 1);

要获取字符串,您只需使用:

text = String.join(" ", list);// "stackoverflow remain only"

如果您使用的是Java 8,您可以这样使用:

String text = "Hello hi hi stackoverflow remain only Hello ";
List<String> list = new ArrayList<>(Arrays.asList(text.split("\\s+")));
list.removeIf(element -> Collections.frequency(list, element) > 1);

要获取字符串,您只需使用:

text = String.join(" ", list);// "stackoverflow remain only"

你的代码看起来太复杂了。相反,使用Java-8流库,您可以执行以下操作:

List<String> result = 
         Pattern.compile("\\s")
                .splitAsStream(name)
                .collect(Collectors.groupingBy(e -> e,
                        LinkedHashMap::new,
                        Collectors.counting()))
                .entrySet()
                .stream()
                .filter(e -> e.getValue() == 1)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());

你的代码看起来太复杂了。相反,使用Java-8流库,您可以执行以下操作:

List<String> result = 
         Pattern.compile("\\s")
                .splitAsStream(name)
                .collect(Collectors.groupingBy(e -> e,
                        LinkedHashMap::new,
                        Collectors.counting()))
                .entrySet()
                .stream()
                .filter(e -> e.getValue() == 1)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
试试这个

Stream.of(str.split(" "))
            .collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(n -> 1)))
            .entrySet()
            .stream()
            .filter(e->e.getValue() == 1)
            .map(e->e.getKey())
            .collect(Collectors.joining(" "))

还是像这样

Set<String> set = new HashSet<>();
List<String> orginal = new ArrayList<>(Arrays.asList(as));
orginal.removeAll(Arrays.stream(as)
                  .filter(str -> !set.add(str))
                  .collect(Collectors.toList()));
Set Set=newhashset();
List original=newarraylist(Arrays.asList(as));
原始.removeAll(数组.stream(as)
.filter(str->!set.add(str))
.collect(Collectors.toList());
试试这个

Stream.of(str.split(" "))
            .collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(n -> 1)))
            .entrySet()
            .stream()
            .filter(e->e.getValue() == 1)
            .map(e->e.getKey())
            .collect(Collectors.joining(" "))

还是像这样

Set<String> set = new HashSet<>();
List<String> orginal = new ArrayList<>(Arrays.asList(as));
orginal.removeAll(Arrays.stream(as)
                  .filter(str -> !set.add(str))
                  .collect(Collectors.toList()));
Set Set=newhashset();
List original=newarraylist(Arrays.asList(as));
原始.removeAll(数组.stream(as)
.filter(str->!set.add(str))
.collect(Collectors.toList());

与@YCF_L的答案略有不同,可能时短路

List<String> list = new ArrayList<>(Arrays.asList(text.split("\\s")));
list.removeIf(element -> list.stream()
                             .filter(e -> e.equals(element)) 
                             .limit(2) // short circuit
                             .count() > 1);
List List=newarraylist(Arrays.asList(text.split(\\s));
list.removeIf(元素->列表.stream()
.过滤器(e->e.equals(元素))
.极限(2)//短路
.count()>1);
更新:

上面的代码是有效的,但是如果您关心从列表中删除的数据流,那么更安全的选择是:

List<String> result = 
      list.stream()
          .filter(element -> list.stream().filter(e -> e.equals(element)).limit(2)
                                 .count() == 1) 
          .collect(Collectors.toList());
列表结果=
list.stream()
.filter(element->list.stream().filter(e->e.equals(element)).limit(2)
.count()=1)
.collect(Collectors.toList());

与@YCF_L的答案略有不同,可能时短路

List<String> list = new ArrayList<>(Arrays.asList(text.split("\\s")));
list.removeIf(element -> list.stream()
                             .filter(e -> e.equals(element)) 
                             .limit(2) // short circuit
                             .count() > 1);
List List=newarraylist(Arrays.asList(text.split(\\s));
list.removeIf(元素->列表.stream()
.过滤器(e->e.equals(元素))
.极限(2)//短路
.count()>1);
更新:

上面的代码是有效的,但是如果您关心从列表中删除的数据流,那么更安全的选择是:

List<String> result = 
      list.stream()
          .filter(element -> list.stream().filter(e -> e.equals(element)).limit(2)
                                 .count() == 1) 
          .collect(Collectors.toList());
列表结果=
list.stream()
.filter(element->list.stream().filter(e->e.equals(element)).limit(2)
.count()=1)
.collect(Collectors.toList());
试试这种方法

    String statement = "Hello hi stackoverflow remain only Hello hi";
    String res = "";
    for (String word : Arrays.asList(statement.split(" "))) {
        String remain = statement.replaceFirst(word, "");
        if(remain.contains(word)) {
            remain=statement.replaceAll(word, "");
        }else {
            res+=word+" ";
        }
    }
    System.out.println(res);
试试这个方法

    String statement = "Hello hi stackoverflow remain only Hello hi";
    String res = "";
    for (String word : Arrays.asList(statement.split(" "))) {
        String remain = statement.replaceFirst(word, "");
        if(remain.contains(word)) {
            remain=statement.replaceAll(word, "");
        }else {
            res+=word+" ";
        }
    }
    System.out.println(res);

你好和你好是“一样”吗?那么“嘿”和“哟”呢?他输入了两次“你好”和“你好”,我想他只是指字符完全匹配的单词。你的限制条件是什么?例如,如果不使用流,我可能会解析到一个
映射
,然后输出count==1的所有内容。但是如果你必须使用一个
列表
,那么解决方案就不一样了。把它分成两部分怎么样?先数一数每个字。在第二次迭代中,只复制那些计数为1的单词?只是一个想法,也许会有帮助。“嘿”和“哟”这是不同的词。如果输出中有任何单词重复出现,则应将其全部删除。Hello和Hi是否“相同”?那么“嘿”和“哟”呢?他输入了两次“你好”和“你好”,我想他只是指字符完全匹配的单词。你的限制条件是什么?例如,如果不使用流,我可能会解析到一个
映射
,然后输出count==1的所有内容。但是如果你必须使用一个
列表
,那么解决方案就不一样了。把它分成两部分怎么样?先数一数每个字。在第二次迭代中,只复制那些计数为1的单词?只是一个想法,也许会有帮助。“嘿”和“哟”这是不同的词。如果输出中有任何重复的单词,它们都应该被删除。这有多复杂
O(n^2)
?我想是的@boristeider我试图让它更高效@一个轻微的改进可能是
list.removeIf(element->list.stream().filter(e->e.equals(element)).limit(2.count()>1)
?@Tavash如果你发现重复的单词,你不需要我的代码,你可以使用
list.removeAll(dup)步骤:1使用空格delimeter将字符串拆分为数组步骤:2创建两个ArrayList一个用于整个字符串,另一个用于重复的单词步骤:3在查找重复的单词时,我只需从拆分的数组中选择一个单词,并将其与所有单词的其余部分进行比较(如果出现任何匹配),然后将其放入重复的ArrayList中。第四步:最后我得到了一个重复单词的列表,并称之为完整单词列表;正如@YCF_L所建议的那样。感觉很好,谢谢大家。这件事的时间复杂度是多少
O(n^2)
?我想是的@boristeider我试图让它更高效@一个轻微的改进可能是
list.removeIf(element->list.stream().filter(e->e.equals(element)).limit(2.count()>1)
?@Tavash如果你发现重复的单词,你不需要我的代码,你可以使用
list.removeAll(dup)步骤:1使用空格分隔符将字符串拆分为数组步骤:2创建两个ArrayList,其中一个用于