Java 二进制搜索不检测重复项?
我有一系列的物品,卡片,都有字符串名称,所以Java 二进制搜索不检测重复项?,java,binary-search,Java,Binary Search,我有一系列的物品,卡片,都有字符串名称,所以 卡c1=新卡(“卡”) Card c2=新卡(“其他卡”) 然后我使用快速排序对列表进行排序,然后在添加更多卡片之前尝试二进制搜索以查看卡片是否已经存在 所以 if(cards.contains(c3)=true) //什么都不做 else 卡片。添加(c3) 我的cards.contains方法是 比较器c=新比较器(){ @凌驾 公共整数比较(卡u1,卡u2){ 返回u1.getName().compareTo(u2.getName()); }
卡c1=新卡(“卡”)
Card c2=新卡(“其他卡”)
然后我使用快速排序对列表进行排序,然后在添加更多卡片之前尝试二进制搜索以查看卡片是否已经存在
所以
if(cards.contains(c3)=true)
//什么都不做
else
卡片。添加(c3)
我的cards.contains方法是
比较器c=新比较器(){
@凌驾
公共整数比较(卡u1,卡u2){
返回u1.getName().compareTo(u2.getName());
}
};
整数指数;
index=Collections.binarySearch(卡片、it、c);
如果(索引==-1){
返回false;
}否则{
返回true;
}
但问题是它在搜索卡片数组,找到不在列表中的卡片,然后说它们在,然后说列表中的卡片不在
我试图添加10000张卡片,其中8000张是唯一的,但是contains方法返回2000张唯一的卡片,当我检查列表时,它们甚至不是唯一的
我试着运行未排序的代码,结果只返回了大约4000个结果,同样的问题是重复卡片,当我使用暴力并只使用base.contains时,它可以工作,但速度非常慢
(如果我在帖子中弄错了什么,也很抱歉,这是我第一次在这里发帖)javadoc声明如下: 使用二进制搜索算法在指定列表中搜索指定对象在进行此调用之前,必须根据指定的比较器(如通过sort(list,comparator)方法)将列表按升序排序。如果未排序,则结果未定义。如果列表包含多个与指定对象相等的元素,则无法保证会找到哪个元素 它还声明它返回: 搜索键的索引(如果它包含在列表中);否则,((插入点)-1)。插入点定义为将键插入列表的点:大于键的第一个元素的索引,或list.size()如果列表中的所有元素都小于指定的键。请注意,这保证了当且仅当找到键时,返回值将>=0 因此,您的列表应该事先排序,否则它将不会返回任何有意义的内容。然后,它返回元素的索引或插入点。当心这个技术性问题。执行后,您应该检查索引处的元素是否实际上是正确的,而不仅仅是插入元素的索引
it
在那里,您可以进行此测试,以查看它是否是您的卡:
//测试找到索引处的卡是否与实际查找的卡同名。
回来!index==cards.length&&cards[index].getName().equals(it.getName());
您还可以覆盖equals
,使其更接近:
返回!index==cards.length&&cards[index]。等于(it);
在这两种情况下,如果插入点位于列表的末尾,我们确保不会出现
ArrayOutOfBoundException
。javadoc声明如下:
使用二进制搜索算法在指定列表中搜索指定对象在进行此调用之前,必须根据指定的比较器(如通过sort(list,comparator)方法)将列表按升序排序。如果未排序,则结果未定义。如果列表包含多个与指定对象相等的元素,则无法保证会找到哪个元素
它还声明它返回:
搜索键的索引(如果它包含在列表中);否则,((插入点)-1)。插入点定义为将键插入列表的点:大于键的第一个元素的索引,或list.size()如果列表中的所有元素都小于指定的键。请注意,这保证了当且仅当找到键时,返回值将>=0
因此,您的列表应该事先排序,否则它将不会返回任何有意义的内容。然后,它返回元素的索引或插入点。当心这个技术性问题。执行后,您应该检查索引处的元素是否实际上是正确的,而不仅仅是插入元素的索引it
在那里,您可以进行此测试,以查看它是否是您的卡:
//测试找到索引处的卡是否与实际查找的卡同名。
回来!index==cards.length&&cards[index].getName().equals(it.getName());
您还可以覆盖equals
,使其更接近:
返回!index==cards.length&&cards[index]。等于(it);
在这两种情况下,如果插入点位于列表的末尾,我们将确保不会出现
ArrayOutOfBoundException
。binarySearch在查找项时提供非负索引
它给出插入位置的补码:~index==-index-1(如果找不到)
- 在a b d e中搜索d得到2
- 在BEG中搜索d得到~2==-3,插入位置为2
int index = Collections.binarySearch(cards, it, c);
return index >= 0;
此外,卡应具有正确的等式:
public class Card implements Comparable<Card> {
...
@Override
public int compareTo(Card other) {
return name.compareTo(other.name);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceOf Card)) {
return false;
}
Card other = (Card) obj;
return name.equals(other.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
}
公共类卡实现可比性{
...
@凌驾
公共int比较(卡其他){
返回name.compareTo(其他.name);
}
@凌驾
公共布尔等于(对象obj){
如果(!(卡的obj实例)){
返回false;
}
卡其他=(卡)obj;