Data structures 谷歌搜索建议的实现
在最近的一次亚马逊采访中,我被要求实现谷歌的“建议”功能。当用户输入“Aeniffer Aninston”时,谷歌建议“你是说Jenifer Aninston吗?”。我试图用散列法来解决这个问题,但无法覆盖角落的情况。请告诉我您对此的想法。有4种最常见的错误类型-Data structures 谷歌搜索建议的实现,data-structures,Data Structures,在最近的一次亚马逊采访中,我被要求实现谷歌的“建议”功能。当用户输入“Aeniffer Aninston”时,谷歌建议“你是说Jenifer Aninston吗?”。我试图用散列法来解决这个问题,但无法覆盖角落的情况。请告诉我您对此的想法。有4种最常见的错误类型- 省略字母:“stck”而不是“stack” 一个字母打字错误:“styck”而不是“stack” 额外字母:“斯塔克”而不是“斯塔克” 相邻字母交换:“satck”而不是“stack” 顺便说一句,我们可以交换的不是相邻的字母,而是任
integer
array[]Array[i]
提供访问第i个字时要跳过的字节数。随机访问文件中的单词应按排序顺序写入。如果您有足够的内存来存储字典,请使用trie
建议更正前,检查键入的单词-如果它在字典中,则不提供任何内容。
更新
生成更正应该由BFS完成-当我尝试DFS时,“Jeniffer”之类的条目显示“编辑距离=3”。DFS不起作用,因为它可以在一个步骤中进行大量更改—例如,Jniffer->nJiffer->enJiffer->eJniffer->Jeniffer
,而不是Jniffer->Jeniffer
BFS生成更正的示例代码
static class Pair
{
private String word;
private byte dist;
// dist is byte because dist<=128.
// Moreover, dist<=6 in real application
public Pair(String word,byte dist)
{
this.word = word;
this.dist = dist;
}
public String getWord()
{
return word;
}
public int getDist()
{
return dist;
}
}
public static void main(String[] args) throws Exception
{
HashSet<String> usedWords;
HashSet<String> dict;
ArrayList<String> corrections;
ArrayDeque<Pair> states;
usedWords = new HashSet<String>();
corrections = new ArrayList<String>();
dict = new HashSet<String>();
states = new ArrayDeque<Pair>();
// populate dictionary. In real usage should be populated from prepared file.
dict.add("Jeniffer");
dict.add("Jeniffert"); //depth 2 test
usedWords.add("Jniffer");
states.add(new Pair("Jniffer", (byte)0));
while(!states.isEmpty())
{
Pair head = states.pollFirst();
//System.out.println(head.getWord()+" "+head.getDist());
if(head.getDist()<=2)
{
// checking reached depth.
//4 is the first depth where we don't generate anything
// swap adjacent letters
for(int i=0;i<head.getWord().length()-1;i++)
{
// swap i-th and i+1-th letters
String newWord = head.getWord().substring(0,i)+head.getWord().charAt(i+1)+head.getWord().charAt(i)+head.getWord().substring(i+2);
// even if i==curWord.length()-2 and then i+2==curWord.length
//substring(i+2) doesn't throw exception and returns empty string
// the same for substring(0,i) when i==0
if(!usedWords.contains(newWord))
{
usedWords.add(newWord);
if(dict.contains(newWord))
{
corrections.add(newWord);
}
states.addLast(new Pair(newWord, (byte)(head.getDist()+1)));
}
}
// insert letters
for(int i=0;i<=head.getWord().length();i++)
for(char ch='a';ch<='z';ch++)
{
String newWord = head.getWord().substring(0,i)+ch+head.getWord().substring(i);
if(!usedWords.contains(newWord))
{
usedWords.add(newWord);
if(dict.contains(newWord))
{
corrections.add(newWord);
}
states.addLast(new Pair(newWord, (byte)(head.getDist()+1)));
}
}
}
}
for(String correction:corrections)
{
System.out.println("Did you mean "+correction+"?");
}
usedWords.clear();
corrections.clear();
// helper data structures must be cleared after each generateCorrections call - must be empty for the future usage.
}
静态类对
{
私有字符串字;
专用字节距离;
//dist是byte,因为dist谢谢你的解释。但是我不理解“生成可能的更正”部分。我想你说的是所有可能的组合。例如,如果有人键入“Jniffer Aninston”,可能的更正是什么,以及它将如何映射到原始单词“Jeniffer Aninston”