import java.util.HashMap;
import java.util.Map;
/**
* Minimum Window in which all the words are found
* @author PRATEEK
*/
class MinWindowContainingAllWords {
private static int minWindow = 9999; // length of minimum window
private static int startWord = 0; // start position
private static int endWord = 0; // end position
/**
* Sub-routine to minumum window in which all words of pattern are found in
* the given string
*
* @param str
* : input String
* @param pat
* : pattern
*/
Map
<String, Integer
> toFind
= new HashMap
<String, Integer
>(); // words // to be
// found
Map
<String, Integer
> found
= new HashMap
<String, Integer
>(); // the set // of
// words
// which
// are
// found
int foundCount = 0;
// left pointer of the window, which is moved when all required wrds are
// found,
// and is moved until any word from required word is found
int tempStart = 0;
// Tokenising Text
String[] words
= str.
split(" "); int sLen = words.length;
// Tokenising Pattern
String[] patTokens
= pat.
split(" "); int pLen = patTokens.length;
// filling the 'toFind' map
toFind.put(val, toFind.get(val) == null ? 1 : toFind.get(val) + 1);
// traversing over text length
for (int index = 0; index < sLen; index++) {
if (!toFind.containsKey(word))
continue;
found.put(word, found.get(word) == null ? 1 : found.get(word) + 1);
if (toFind.get(word) >= found.get(word))
foundCount++;
if (foundCount == pLen) {
// reduce window size until conditions are violated
word = words[tempStart];
while (!toFind.containsKey(word)
|| toFind.get(word) < found.get(word)) {
// Discard excess count of the given word
if (toFind.containsKey(word))
found.put(word, found.get(word) - 1);
// get next word, to check if it can be discarded
word = words[++tempStart];
}
// Updating Min Window
if (minWindow > index - tempStart + 1) {
minWindow = index - tempStart + 1;
startWord = tempStart;
endWord = index;
}
}
}
}
public static void main
(String[] args
) {
String str
= "Shopping with xyz.com is an awesome experience"; String pat
= "awesome with xyz.com"; minWindow(str, pat);
//System.out.println("Start :" + startWord + " End : " + endWord);
System.
out.
println("Window Containing all words"); // Tokenising Text
String[] words
= str.
split(" "); for(int i=startWord;i<=endWord;i++)
{
System.
err.
print(words
[i
]+" "); }
}
}
CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgovKioKICogTWluaW11bSBXaW5kb3cgaW4gd2hpY2ggYWxsIHRoZSB3b3JkcyBhcmUgZm91bmQKICogQGF1dGhvciBQUkFURUVLCiAqLwogY2xhc3MgTWluV2luZG93Q29udGFpbmluZ0FsbFdvcmRzIHsKCglwcml2YXRlIHN0YXRpYyBpbnQgbWluV2luZG93ID0gOTk5OTsgLy8gbGVuZ3RoIG9mIG1pbmltdW0gd2luZG93Cglwcml2YXRlIHN0YXRpYyBpbnQgc3RhcnRXb3JkID0gMDsgLy8gc3RhcnQgcG9zaXRpb24KCXByaXZhdGUgc3RhdGljIGludCBlbmRXb3JkID0gMDsgLy8gZW5kIHBvc2l0aW9uCgoJLyoqCgkgKiBTdWItcm91dGluZSB0byBtaW51bXVtIHdpbmRvdyBpbiB3aGljaCBhbGwgd29yZHMgb2YgcGF0dGVybiBhcmUgZm91bmQgaW4KCSAqIHRoZSBnaXZlbiBzdHJpbmcKCSAqIAoJICogQHBhcmFtIHN0cgoJICogICAgICAgICAgICA6IGlucHV0IFN0cmluZwoJICogQHBhcmFtIHBhdAoJICogICAgICAgICAgICA6IHBhdHRlcm4KCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIG1pbldpbmRvdyhTdHJpbmcgc3RyLCBTdHJpbmcgcGF0KSB7CgoJCU1hcDxTdHJpbmcsIEludGVnZXI+IHRvRmluZCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsgLy8gd29yZHMKCQkJCQkJCQkJCQkJCQkJCQkJLy8gdG8gYmUKCQkJCQkJCQkJCQkJCQkJCQkJLy8gZm91bmQKCQlNYXA8U3RyaW5nLCBJbnRlZ2VyPiBmb3VuZCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsgLy8gdGhlIHNldAoJCQkJCQkJCQkJCQkJCQkJCQkvLyBvZgoJCQkJCQkJCQkJCQkJCQkJCQkvLyB3b3JkcwoJCQkJCQkJCQkJCQkJCQkJCQkvLyB3aGljaAoJCQkJCQkJCQkJCQkJCQkJCQkvLyBhcmUKCQkJCQkJCQkJCQkJCQkJCQkJLy8gZm91bmQKCgkJaW50IGZvdW5kQ291bnQgPSAwOwoJCS8vIGxlZnQgcG9pbnRlciBvZiB0aGUgd2luZG93LCB3aGljaCBpcyBtb3ZlZCB3aGVuIGFsbCByZXF1aXJlZCB3cmRzIGFyZQoJCS8vIGZvdW5kLAoJCS8vIGFuZCBpcyBtb3ZlZCB1bnRpbCBhbnkgd29yZCBmcm9tIHJlcXVpcmVkIHdvcmQgaXMgZm91bmQKCQlpbnQgdGVtcFN0YXJ0ID0gMDsKCgkJLy8gVG9rZW5pc2luZyBUZXh0CgkJU3RyaW5nW10gd29yZHMgPSBzdHIuc3BsaXQoIiAiKTsKCQlpbnQgc0xlbiA9IHdvcmRzLmxlbmd0aDsKCgkJLy8gVG9rZW5pc2luZyBQYXR0ZXJuCgkJU3RyaW5nW10gcGF0VG9rZW5zID0gcGF0LnNwbGl0KCIgIik7CgkJaW50IHBMZW4gPSBwYXRUb2tlbnMubGVuZ3RoOwoKCQkvLyBmaWxsaW5nIHRoZSAndG9GaW5kJyBtYXAKCQlmb3IgKFN0cmluZyB2YWwgOiBwYXRUb2tlbnMpCgkJCXRvRmluZC5wdXQodmFsLCB0b0ZpbmQuZ2V0KHZhbCkgPT0gbnVsbCA/IDEgOiB0b0ZpbmQuZ2V0KHZhbCkgKyAxKTsKCgkJLy8gdHJhdmVyc2luZyBvdmVyIHRleHQgbGVuZ3RoCgkJZm9yIChpbnQgaW5kZXggPSAwOyBpbmRleCA8IHNMZW47IGluZGV4KyspIHsKCQkJU3RyaW5nIHdvcmQgPSB3b3Jkc1tpbmRleF07CgoJCQlpZiAoIXRvRmluZC5jb250YWluc0tleSh3b3JkKSkKCQkJCWNvbnRpbnVlOwoKCQkJZm91bmQucHV0KHdvcmQsIGZvdW5kLmdldCh3b3JkKSA9PSBudWxsID8gMSA6IGZvdW5kLmdldCh3b3JkKSArIDEpOwoKCQkJaWYgKHRvRmluZC5nZXQod29yZCkgPj0gZm91bmQuZ2V0KHdvcmQpKQoJCQkJZm91bmRDb3VudCsrOwoKCQkJaWYgKGZvdW5kQ291bnQgPT0gcExlbikgewoJCQkJLy8gcmVkdWNlIHdpbmRvdyBzaXplIHVudGlsIGNvbmRpdGlvbnMgYXJlIHZpb2xhdGVkCgkJCQl3b3JkID0gd29yZHNbdGVtcFN0YXJ0XTsKCQkJCXdoaWxlICghdG9GaW5kLmNvbnRhaW5zS2V5KHdvcmQpCgkJCQkJCXx8IHRvRmluZC5nZXQod29yZCkgPCBmb3VuZC5nZXQod29yZCkpIHsKCQkJCQkvLyBEaXNjYXJkIGV4Y2VzcyBjb3VudCBvZiB0aGUgZ2l2ZW4gd29yZAoJCQkJCWlmICh0b0ZpbmQuY29udGFpbnNLZXkod29yZCkpCgkJCQkJCWZvdW5kLnB1dCh3b3JkLCBmb3VuZC5nZXQod29yZCkgLSAxKTsKCgkJCQkJLy8gZ2V0IG5leHQgd29yZCwgdG8gY2hlY2sgaWYgaXQgY2FuIGJlIGRpc2NhcmRlZAoJCQkJCXdvcmQgPSB3b3Jkc1srK3RlbXBTdGFydF07CgkJCQl9CgoJCQkJLy8gVXBkYXRpbmcgTWluIFdpbmRvdwoJCQkJaWYgKG1pbldpbmRvdyA+IGluZGV4IC0gdGVtcFN0YXJ0ICsgMSkgewoJCQkJCW1pbldpbmRvdyA9IGluZGV4IC0gdGVtcFN0YXJ0ICsgMTsKCQkJCQlzdGFydFdvcmQgPSB0ZW1wU3RhcnQ7CgkJCQkJZW5kV29yZCA9IGluZGV4OwoJCQkJfQoJCQl9CgkJfQoJfQoKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKCgkJU3RyaW5nIHN0ciA9ICJTaG9wcGluZyB3aXRoIHh5ei5jb20gaXMgYW4gYXdlc29tZSBleHBlcmllbmNlIjsKCQlTdHJpbmcgcGF0ID0gImF3ZXNvbWUgd2l0aCB4eXouY29tIjsKCQltaW5XaW5kb3coc3RyLCBwYXQpOwoJCS8vU3lzdGVtLm91dC5wcmludGxuKCJTdGFydCA6IiArIHN0YXJ0V29yZCArICIgICBFbmQgOiAiICsgZW5kV29yZCk7CgoJCVN5c3RlbS5vdXQucHJpbnRsbigiV2luZG93IENvbnRhaW5pbmcgYWxsIHdvcmRzIik7CgkJLy8gVG9rZW5pc2luZyBUZXh0CgkJU3RyaW5nW10gd29yZHMgPSBzdHIuc3BsaXQoIiAiKTsKCQlmb3IoaW50IGk9c3RhcnRXb3JkO2k8PWVuZFdvcmQ7aSsrKQoJCXsKCQkJU3lzdGVtLmVyci5wcmludCh3b3Jkc1tpXSsiICAiKTsKCQl9CgoJfQp9Cg==