Finding missing words in string

Viewed 9887

I am trying to solve a problem of finding missing words in a string.

For example:
Input
String 1 = "I love programming, pizza, coke and chips";
String 2 = "I programming, chips";
Required Output
Missing words = "love pizza coke";

Note: the order of output has to be same (this is where I am messing up)

what I have so far, but I am getting wrong results.

public static List<String> findWord(String s, String t) {
    HashSet<String> missingWords = new HashSet<>();
    String[] words = s.split(" ");
    for(int i=0; i < words.length; i++) {
        if (!t.contains(words[i])) {
            missingWords.add(words[i]);
        }
    }
    List<String> ans = new ArrayList<String>();
    for (String str: missingWords) {
        ans.add(str);
    }

    return ans;
}
6 Answers

I would approach this by splitting both input strings, stripping off punctuation, and then walking down each array of words, in the original order. When encountering a match, both lists advance. When there is no match, the original list advances, but the second list does not, and we also record the original word as not having found a match.

The key point here is that we use an ArrayList, which maintains insertion order, while traversing.

String input = "I love programming, pizza, coke and chips";
String other = "I programming, chips";
String[] parts = input.replaceAll("[,.;-]", "").split("\\s");
String[] otherparts = other.replaceAll("[,.;-]", "").split("\\s");
List<String> missing = new ArrayList<>();
int pnt = 0;
for (int i=0; i < parts.length; ++i) {
    if (parts[i].equals(otherparts[pnt])) {
        ++pnt;
    }
    else {
        missing.add(parts[i]);
    }
}

System.out.println(Arrays.toString(parts));
System.out.println(Arrays.toString(missing.toArray()));

[I, love, programming, pizza, coke, and, chips]
[love, pizza, coke, and]

Demo

Demo added for informational purposes only. Do not rely on it for production use.

HashSet is an un-ordered collection and its not possible to store element in any order, but if you have to access elements of HashSet in sorted order then you can first convert it to List and then sort it out

HashSet<String> missingWords = new HashSet<>();
...
missingWords.add(words[i]);// <== the order here is correct
...
for(String str: missingWords){// <== the order here is incorrect
   ans.add(str);
}

Hope you will find it useful.

This is very simple problem.

  1. Split both string with words using RegExp: \W+
  2. Expected words put into HashSet: unique not ordered
  3. Existed words put into ArrayList: not unique ordered
  4. Remove all words from the List that not contain in Set: removeAll()

Demo:

public static List<String> findMissingWords(String str, String expectedWords) {
    Set<String> expected = Arrays.stream(expectedWords.split("\\W+")).collect(Collectors.toSet());
    List<String> existed = Arrays.stream(str.split("\\W+")).collect(Collectors.toList());
    existed.removeAll(expected);
    return existed;
}

In order to maintain the order of insertion, you should use LinkedHashSet instead of HashSet.

String s = "I love programming, pizza, coke and chips";
        String t = "I programming, chips";

         LinkedHashSet<String> missingWords = new LinkedHashSet<>(); //<---to maintain the order
            String[] words = s.split(" ");
            for(int i=0; i < words.length; i++) {
                if (!t.contains(words[i])) {
                    missingWords.add(words[i].replaceAll(",", "")); //<---add without comma
                }
            }
            List<String> ans = new ArrayList<String>();
            for (String str: missingWords) {
                ans.add(str);
            }

            System.out.println(ans);

Output:[love, pizza, coke, and]

Please try below code:

 public static void main(String []args){
    String s = "I love programming, pizza, coke and chips";
    String t = "I programming, chips";
    
    String[] firstWord = s.replaceAll(",","").split("\\s+");
    String[] secondWord = t.replaceAll(",","").split("\\s+");
    ArrayList<String> temp1 = new ArrayList<String>(Arrays.asList(firstWord));
    ArrayList<String> temp3 = new ArrayList<String>(Arrays.asList(firstWord));
    ArrayList<String> temp2 = new ArrayList<String>(Arrays.asList(secondWord));
    
    ArrayList<String> finals = new ArrayList<String>();
    
    finals.addAll(missingWords(temp1, temp2));
    finals.addAll(missingWords(temp2, temp3));
    
    System.out.println(finals);
 }
 
 static ArrayList<String> missingWords(ArrayList<String> str1, ArrayList<String> str2) {

     str1.removeAll(str2);
     
     return str1;
 }

split the two strings with space separator, then use the in_array function

Related