在null
的二进制搜索过程中处理List<string>
的最佳方法是什么(如果可以的话, 将成为List<string>
事先读出所有的值?)
int previous = 0;
int direction = -1;
if (itemToCompare == null) {
previous = mid;
for (int tries = 0; tries < 2; tries++) {
mid += direction;
itemToCompare = GetItem(mid);
while (itemToCompare == null && insideInclusiveRange(min, max, mid)) {
mid += direction;
itemToCompare = GetItem(mid);
}
if (!insideInclusiveRange(min, max, mid)) {
/* Reached an endpoint without finding anything,
try the other direction. */
mid = previous;
direction = -direction;
} else if (itemToCompare != null) {
break;
}
}
}
我目前正在做类似上面的事情 - 如果遇到null,则在一个方向上进行线性搜索,直到遇到非null 或超出端点为止,如果没有成功,然后在其他方向重复。在实际代码中,我从先前的比较结果中获得direction
,并且GetItem()
缓存它检索的值。是否有一种更简单的方法,没有制作非空值的中间列表(由于上面的GetItem()
函数很慢,我的目的需要太长时间)?
我想我在问是否有一种更聪明的方法来处理空值而不是降级为线性搜索。很可能只有一小部分的空值(1-5%),但是可能,因为有100个空的序列。
编辑 - 数据看起来像这样
aa aaa b bb bbb c cc d ddd
其中每一行都是一个单独的对象,并不保证所有单元格都被填充。用户需要能够搜索整行(以便“bb”和“bbb”都匹配整个第二行)。查询每个对象的速度足够慢,线性搜索不起作用。出于同样的原因,创建一个没有空值的新列表并不可行。
答案 0 :(得分:2)
除非有理由选择/找到null
值(不确定这意味着null
是单身,并且二元搜索通常最需要唯一值),考虑不允许它们在列表中。
[上一个回答:在对问题进行反思之后,我已经确定null
可能在问题空间中没有位置 - 酌情采取比特和部分。] < / p>
如果需要空值,只需对列表进行排序,使空值为第一个(或最后一个)并正确更新逻辑 - 然后确保不在任何null
值上调用方法; - )
由于已经需要排序,因此整体影响不大。如果项目更改为null
- 这听起来像一个icky副作用! - 然后只是“压缩”List(例如“删除”空项)。但是,除非有充分的理由,否则我只会不修改排序列表。
二进制搜索只是真正设计/适用于(完全)排序数据。没有必要把它变成二进制可能是线性的搜索。
快乐的编码。