为什么compareTo 在应该为 false 的时候却返回 true ?

发布于 2024-09-29 23:03:02 字数 1293 浏览 5 评论 0原文

我正在调试数据结构类项目的错误搜索返回。当前的项目要求我们构建一个有序的展开链表,并对内容进行搜索,然后返回从包含起点到排他终点的项目子列表。为了做到这一点,我必须搜索内部数组以找到起始元素的索引点。我通过二分搜索来执行此操作,但由于这仅返回第一个找到的匹配项,并且在它之前可能还有其他匹配项,因此我必须返回数组以找到第一个真正的匹配项。我通过教授提供的测试代码来完成此操作

//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++ 进行补偿,这足以通过结构测试,但与预期的起点相差一分。

那么为什么当它明显是 false 时却返回 true 呢?

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

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

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

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

I'm debugging erroneous search returns from my data structures class project. This current project required us to build an ordered unrolled linked list, and run a search on the contents, then return a sublist of items from an inclusive start point to an exclusive end point. In order to do this, I have to search the internal array to find the index point of the start element. I do this by binary search, but since this only returns the first found match and there may be other matches before it, I have to work back in the array to find the first true match. I do this via

//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--;
}

The professor provided testing code which breaks up a String and adds each character as an item in the structure. He also included a nested StringCmp class, which is referenced as comp in the binary search declaration above. His compare method is

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

However, when running a test on the sublist method from i to o, this method is returning a true value when comp.compare(h,i)==0 and this is throwing my start results off from the search class I wrote. I originally compensated by return index++ which sufficed to pass the structure test, but threw off the expected start point by one.

So why is this returning true when it is obviously false?

EDIT added printout of sublist method, expected to run from i to o

Input test string= abcdefghijklmnopqrstuvwxyzaeiou
Return from sublist method:
chunk 1 (used 4 of 10): [h][i][i][j]
chunk 2 (used 4 of 10): [k][l][m][n]

The h should not be in the list at all, but the comp.compare(node.items[index], item)==0 is returning true that i == h, which is obviously false.

Edit two
The second part of the project requires us to parse a text file, build Song objects from Artist, Title and Lyrics fields, and then run a search on the titles using a prefix. The bug occurring here does not occur in single and multi-letter searches, so I think the problem is with the StringCmp nested class in the test.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

橘亓 2024-10-06 23:03:02

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

另外,什么在对数组执行排序?您能否发布您的 binarySearch() 代码,以便我们看看问题是否出在此处?

Do you know what compare() is supposed to return? Generally functions like that return a negative value if the first argument is less than the second, 0 if they are equal, and a positive value if the first argument is greater than the second.

Also, what is performing the sort on your array? Could you post your binarySearch() code so we can see if the problem lies there?

咿呀咿呀哟 2024-10-06 23:03:02

当您减少每场比赛的索引时,您的 while 循环

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

会超出第一个匹配项,从而使您的索引不再匹配。相反,对索引 1 处的项目调用比较器可以解决此问题:

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

your while-loop

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

overshoots the first match by one as you're decrementing index for every match, leaving you at an index that no longer matches. Calling the Comparator on the item at index-1 instead would fix this:

while (index>0 && comp.compare(node.items[index-1], item)==0){
    index--;
}
ゞ记忆︶ㄣ 2024-10-06 23:03:02

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

您当前的方法引入了不必要的复杂性,并且如果您的输入数组由所有相同的值组成,则可能会将 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;

Since you implemented your own binary search, you should continue to use this to search for the first matching element in the array, instead of stopping as soon as you have found a match.

Your current approach introduces unnecessary complexity, and potentially changes a O(log N) algorithm into an O(N) one if your input array consists of all identical values.

I assume your current algorithm looks something like

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;

replacing this with the code below should do the trick

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;
南…巷孤猫 2024-10-06 23:03:02

查看官方说明compareTo(String) 方法的

来自文档:

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

Check official description of the compareTo(String) method

From the doc:

Returns: the value 0 if the argument string is equal to this string; a value less than 0 if this string is lexicographically less than the string argument; and a value greater than 0 if this string is lexicographically greater than the string argument.

面犯桃花 2024-10-06 23:03:02

出于好奇,这不是更符合您想要做的事情吗?

//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;
}

Out of curiosity, wouldn't this be more in-line for what you're trying to do?

//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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文