这是一个有趣的问题。
给定字典的接口。它的大小,分布和内容都是未知的。升序排序。
我们只有一种方法
String getWord(long index) throws IndexOutOfBoundsException
向API中添加一个方法:
boolean isInDictionary(String word)
这个问题的最佳实现是什么。
答案 0 :(得分:1)
这是我的实施
boolean isWordInTheDictionary(String word){
if (word == null){
return false;
}
// estimate the length of the dictionary array
long len=2;
String temp= getWord(len);
while(true){
len = len * 2;
try{
temp = getWord(len);
}catch(IndexOutOfBoundsException e){
// found upped bound break from loop
break;
}
}
// Do a modified binary search using the estimated length
long beg = 0 ;
long end = len;
String tempWrd;
while(true){
System.out.println(String.format("beg: %s, end=%s, (beg+end)/2=%s ", beg,end,(beg+end)/2));
if(end - beg <= 1){
return false;
}
long idx = (beg+end)/2;
tempWrd = getWord(idx);
if(tempWrd == null){
end=idx;
continue;
}
if ( word.compareTo(tempWrd) > 0){
beg = idx;
}
else if(word.compareTo(tempWrd) < 0){
end= idx;
}else{
// found the word..
System.out.println(String.format("getword at index: %s, =%s", idx,getWord(idx)));
return true;
}
}
}
如果这是正确的,请告诉我
答案 1 :(得分:0)
让我们假设您的假设数据结构及其单一方法String getWord(long index)
基于实现usual Dictionary operations的词典:
但除了最后一个以外的所有方法都被隐藏了。
如果是这种情况,那么您的代码肯定是不正确的,因为没有理由认为字典以任何特定顺序存储值,因此使用word.compareTo()
对项目进行二进制搜索不能期待工作。
此外,您没有catch
代码用于字典大小和len
之间的索引号,您发现的大于字典大小的2的幂,不一定是2的幂,所以即使你改为线性搜索而不是二进制,你也有一个未处理的单词的未处理异常。
答案 2 :(得分:0)
不,字典中的单词可能没有排序。因此,您必须遍历字典并检查每个单词是否是您正在寻找的单词。
如果它已经排序,那么您的解决方案可以得到改善。第一个循环只需要在你的单词之后找到最合适的条目,你正在搜索。
答案 3 :(得分:0)
duedl0r是正确的,你不能假设字典会被订购。
没有任何其他信息,可能随机搜索是您可以选择的最佳算法(在估算大小或估算期间)
只是为了纠正,在算法的第二部分你应该检查异常并处理它们,因为正如你在评论中所说的,你的估计只是一个上限,而在getWord期间你有可能赶上一个
修改:只是为了给出更好的解释
在未排序列表中搜索时间复杂度的下界等于O(n)
randomized search的复杂度等于O(k),其中 k 是搜索中的迭代。所以,你可以决定 k 。但重要的是要了解随机搜索不能保证成功
当 n ,字典的大小非常大时,你可以将 k 设置为低于 n 的一些订单并具有高概率找到这个词