Tavash
Tavash

Reputation: 101

How to delete all repeated words from the string even none of the repeated words remain?

Sample input

"Hello hi hi stackoverflow remain only Hello " 

output:

"stackoverflow remain only"

Here is my code I tried

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));
        }
    }
}

Upvotes: 1

Views: 116

Answers (5)

Mohammad
Mohammad

Reputation: 739

Try this approach

    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);

Upvotes: 0

Ousmane D.
Ousmane D.

Reputation: 56423

A slightly different variant to @YCF_L's answer, short-circuiting where possible.

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);

Update:

The above code works, but if you're concerned with streaming over a list you're removing from then a safer alternative would be:

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

Upvotes: 1

Hadi
Hadi

Reputation: 17289

Try this one

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(" "))

or like this

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()));

Upvotes: 1

Youcef LAIDANI
Youcef LAIDANI

Reputation: 59950

If you are using Java 8 you can use removeIf and Collection.frequency like this :

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);

The idea is to remove all element which has a frequency great than 1.

Outputs

[stackoverflow, remain, only]

to get back a String you can just use :

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

Upvotes: 2

Ousmane D.
Ousmane D.

Reputation: 56423

Your code looks too complicated. instead, using the Java-8 stream library, you can do:

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());

or if you want the receiver type as a String then you can use the joining collector.

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.joining(" "));

Upvotes: 2

Related Questions