Skip to content

Instantly share code, notes, and snippets.

@mrboli
Created April 12, 2020 18:38
Show Gist options
  • Save mrboli/0c531cacef6804f35e7cbf75a717e63e to your computer and use it in GitHub Desktop.
Save mrboli/0c531cacef6804f35e7cbf75a717e63e to your computer and use it in GitHub Desktop.
Autocomplete
/**
* @param {string[]} sentences
* @param {number[]} times
*/
var AutocompleteSystem = function(sentences, times) {
this.trie = { letters: {} };
this.sentences = {};
this.searchInput = '';
sentences.forEach((sentence, sentenceIdx) => {
this.addSentence(sentence, times[sentenceIdx]);
});
this.searchNode = this.trie;
};
AutocompleteSystem.prototype.addSentence = function (sentence, times) {
let trieNode = this.trie;
if (sentence in this.sentences === false) {
if (times == null) { // clean
this.sentences[sentence] = { sentence, times: 1 };
} else {
this.sentences[sentence] = { sentence, times };
}
} else this.sentences[sentence].times++;
sentence.split('').forEach((letter, i) => {
if (letter in trieNode.letters === false) {
trieNode.letters[letter] = { letters: {} };
}
if (i >= sentence.length - 1) {
trieNode.letters[letter].sentences = [this.sentences[sentence]];
// add sentence shortcut here
// for (let i = sentence.length - 1; i >= 0; i--) {
// }
} else {
trieNode = trieNode.letters[letter];
}
});
}
/**
* @param {character} c
* @return {string[]}
*/
AutocompleteSystem.prototype.input = function(c) {
if (c === '#') {
this.addSentence(this.searchInput);
this.searchInput = '';
this.searchNode = this.trie;
return [];
}
this.searchInput += c;
if (c in this.searchNode.letters) {
this.searchNode = this.searchNode.letters[c];
return this.getSearchResults();
} else {
this.searchNode = { letters: {} };
return [];
}
};
AutocompleteSystem.prototype.getSearchResults = function () {
let resultWords = drillNode(this.searchNode);
function drillNode (searchNode) {
let resultWords = [];
if (searchNode && searchNode.sentences)// return searchNode.sentences;
resultWords = resultWords.concat(searchNode.sentences);
Object.keys(searchNode.letters).forEach(letter => {
let letterWords = drillNode(searchNode.letters[letter]);
if (letterWords && letterWords.length > 0)
resultWords = resultWords.concat(letterWords);
});
return resultWords;
}
resultWords.sort(function (prev, next) {
let timeDiff = next.times - prev.times;
if (timeDiff === 0) {
return prev.sentence.localeCompare(next.sentence);
}
return timeDiff;
})
return resultWords.map(resultObject => resultObject.sentence).slice(0, 3);
};
/**
* Your AutocompleteSystem object will be instantiated and called as such:
* var obj = new AutocompleteSystem(sentences, times)
* var param_1 = obj.input(c)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment