为什么compareTo应该为false时返回true?

时间:2010-10-29 13:14:20

标签: java data-structures string-comparison

我正在从我的数据结构类项目中调试错误的搜索返回。当前项目要求我们构建有序的展开链表,并对内容进行搜索,然后将项目子列表从包含起点返回到独占终点。为了做到这一点,我必须搜索内部数组以找到start元素的索引点。我通过二分搜索来做到这一点,但由于这只返回第一个找到的匹配,并且在它之前可能还有其他匹配,我必须在数组中返回才能找到第一个真正的匹配。我通过

这样做
//get first index match, work backwards
int index= binarySearch(node.items, 0, node.numUsed, item, comp);
while (index>0 && comp.compare(node.items[index], item)==0){
    index--;
}

教授提供了测试代码,用于分解字符串并将每个字符添加为结构中的项目。他还包括一个嵌套的StringCmp类,在上面的二进制搜索声明中引用为comp。他的比较方法是

public int compare(String s1, String s2) {
  cmpCnt++;
  return s1.compareTo(s2);
}

但是,当从i到o运行子列表方法的测试时,此方法在comp.compare(h,i)==0时返回一个真值,这是从我写的搜索类中抛出我的开始结果。我最初用return index++补偿了足以通过结构测试,但是把预期的起点推迟了一个。

那么为什么当它显然是假的时候会返回真的呢?

编辑添加了子列表方法的打印输出,预计从i运行到o

输入测试字符串= abcdefghijklmnopqrstuvwxyzaeiou 从子列表方法返回:
块1(使用4个中的4个):[h] [i] [i] [j]
块2(使用4个中的4个):[k] [l] [m] [n]

h根本不应该在列表中,但是comp.compare(node.items[index], item)==0返回true,即i == h,这显然是假的。

编辑两个 项目的第二部分要求我们解析文本文件,从Artist,Title和Lyrics字段构建Song对象,然后使用前缀对标题进行搜索。这里发生的错误不会发生在单字母和多字母搜索中,所以我认为问题在于测试中的StringCmp嵌套类。

5 个答案:

答案 0 :(得分:5)

你知道compare()应该返回什么吗?通常,如果第一个参数小于第二个参数,则返回负值,如果它们相等则返回0,如果第一个参数大于第二个参数,则返回正值。

此外,在您的阵列上执行排序的是什么?您可以发布binarySearch()代码,以便我们查看问题是否存在?

答案 1 :(得分:2)

你的while循环

while (index>0 && comp.compare(node.items[index], item)==0){
    index--;
}
当你为每个匹配减少索引时,

将第一个匹配超过一个,从而使你处于一个不再匹配的索引。在index-1上调用项目上的Comparator会改为:

while (index>0 && comp.compare(node.items[index-1], item)==0){
    index--;
}

答案 2 :(得分:1)

由于您实现了自己的二进制搜索,因此您应该继续使用它来搜索数组中的第一个匹配元素,而不是在找到匹配项后立即停止。

您当前的方法会引入不必要的复杂性,如果输入数组包含所有相同的值,则可能会将O(log N)算法更改为O(N)算法。

我假设您当前的算法类似于

int low = 0; 
int high = a.length-1;
while (low <= high) {
    int mid = (low + high) / 2;
    int cmp = comp.compare(a[mid], key);
    if (cmp < 0)
        low = mid + 1;
    else if (cmp > 0)
        high = mid - 1;
    else
        return mid;
}
return -1;

用下面的代码替换它应该可以做到这一点

int low = 0;
int high = a.length-1;
while (low < high) {
    int mid = (low + high) / 2;
    int cmp = comp.compare(a[mid], key);
    if (cmp < 0)
        low = mid + 1;
    else
        high = mid;
}
if (comp.compare(a[low], key) == 0)
    return low;
else 
    return -1;

答案 3 :(得分:0)

检查compareTo(String)方法的official description

来自doc:

返回:如果参数字符串等于此字符串,则返回值0;如果此字符串按字典顺序小于字符串参数,则小于0的值;如果此字符串按字典顺序大于字符串参数,则值大于0.

答案 4 :(得分:0)

出于好奇,这不会更符合您的目标吗?

//get first index match, work backwards
int index= binarySearch(node.items, 0, node.numUsed, item, comp);

for (int i = index; i >= 0; i--) {
    if (comp.compare(node.items[index], item)==0))
        index = i;
}