在 bsearch() 中自定义比较
我有一个指向整数的地址数组(这些整数 按升序排列)。它们有重复的值。例如:1, 2, 2, 3, 3, 3, 3, 4, 4......
我试图获取所有大于a的值 一定的值(键)。目前正在尝试使用二进制来实现它 搜索算法 -
void *bsearch(
const void *key,
const void *base,
size_t num,
size_t width,
int ( __cdecl *compare ) ( const void *, const void *)
);
我无法完全实现这一点,但对于其中一些算法来说。
是否有其他方法可以获取所有值 数组,而不改变我正在使用的算法?
I have an array of addresses that point to integers ( these integers
are sorted in ascending order). They have duplicate values. Ex: 1,
2, 2, 3, 3, 3, 3, 4, 4......
I am trying to get hold of all the values that are greater than a
certain value(key). Currently trying to implement it using binary
search algo -
void *bsearch(
const void *key,
const void *base,
size_t num,
size_t width,
int ( __cdecl *compare ) ( const void *, const void *)
);
I am not able to achieve this completely, but for some of them.
Would there be any other way to get hold of all the values of the
array, with out changing the algorithm I am using?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如 Klatchko 和 GMan 所指出的,STL 函数完全满足您的要求: std ::上限。
不过,如果您需要坚持使用 bsearch,最简单的解决方案可能是向前迭代,直到达到新值。
如果您想获取第一个与 key 匹配的 p,而不是第一个较大的 p,只需使用
--p
而不是++p
。正如迈克尔建议的那样,您是否喜欢这种搜索还是重复的二分搜索取决于数组的大小以及您期望的重复次数。
现在,您的问题标题指的是自定义比较函数,但据我了解,这个问题在这里对您没有帮助 - 比较函数必须将任何两个等效对象比较为等效,因此对于识别几个等效对象中的哪一个没有好处是数组中该类型的第一个/最后一个。除非您遇到不同的问题,特别是关于比较函数的问题?
As Klatchko and GMan have noted, the STL function gives you exactly what you're asking: std::upper_bound.
If you need to stick with bsearch, though, the simplest solution may be to iterate forwards until you reach a new value.
If you want to get the first p that matches key, rather than the first one that's larger, just use
--p
instead of++p
.Whether you prefer this or a repeated binary search, as Michael suggests, depends on the size of the array and how many repetitions you expect.
Now, your question title refers to customizing the compare function, but as I understand the question that won't help you here - the compare function must compare any two equivalent objects as being equivalent, so it's no good for recognizing which of several equivalent objects is the first/last of its type in an array. Unless you had a different problem, specifically concerning the compare function?
您应该查看 std::upper_bound
例如,要查找第一个值> 3:
相关函数是std::lower_bound。
You should look into std::upper_bound
For example, to find the address of the first value > 3:
A related function is std::lower_bound.
是的,您可以使用二分搜索。诀窍是当您找到具有给定键的元素时您要做的事情...除非您的下索引和上索引相同,否则您需要在间隔的左侧部分继续二分搜索...也就是说,您应该移动上限为当前中点。这样,当二分搜索终止时,您将找到第一个这样的元素。然后迭代其余部分。
Yes, you can use a binary search. The trick is what you do when you find an element with the given key... unless your lower and upper indices are the same, you need to continue binary searching in the left part of your interval... that is, you should move the upper bound to be the current midpoint. That way, when your binary search terminates, you will have found the first such element. Then just iterate over the rest.
如果您实现了二叉搜索树,则可以使用树遍历算法来执行此操作。您可以到达所需的“上限”节点并从那里简单地按顺序遍历。遍历比多次搜索树要简单,即遍历n个节点的树最多需要n次操作,而搜索n次需要(n.log n) 运营。
If you have a binary search tree implemented, you have tree traversal algorithms to do this. You could reach the required 'upper-bound' node and simply traverse in-order from there. Traversal is simpler than searching the tree multiple times, i.e, traversing a tree of n nodes would take n operations at most, whereas searching n times would take (n.log n) operations.