memcmp排序
我有一个缓冲区和几个指向它的指针。 我想根据指针指向的缓冲区中的字节对指针进行排序。
qsort() 和 stl::sort() 可以被赋予自定义比较函数。 例如,如果缓冲区是零终止的,我可以使用 strcmp:
int my_strcmp(const void* a,const void* b) {
const char* const one = *(const char**)a,
const two = *(const char**)b;
return ::strcmp(one,two);
}
但是,如果缓冲区不是零终止的,我必须使用需要长度参数的 memcmp() 。
有没有一种整洁、有效的方法可以在不使用全局变量的情况下将缓冲区的长度输入到我的比较函数中?
I have a single buffer, and several pointers into it. I want to sort the pointers based upon the bytes in the buffer they point at.
qsort() and stl::sort() can be given custom comparision functions. For example, if the buffer was zero-terminated I could use strcmp:
int my_strcmp(const void* a,const void* b) {
const char* const one = *(const char**)a,
const two = *(const char**)b;
return ::strcmp(one,two);
}
however, if the buffer is not zero-terminated, I have to use memcmp() which requires a length parameter.
Is there a tidy, efficient way to get the length of the buffer into my comparision function without a global variable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
使用 std::sort,您可以使用像这样的 Functor:
然后您可以执行以下操作:
编辑: 来自注释建议(我猜这两个字符串都在公共缓冲区中?):
With std::sort, you can use a Functor like this:
Then you can do this:
EDIT: from the comment suggestions (i guess both strings are in a common buffer?):
对于 C 函数
qsort()
,不,如果不使用全局变量,就无法将长度传递给比较函数,这意味着它不能以线程安全的方式完成。 有些系统有qsort_r()
函数(r 代表可重入),它允许您传递额外的上下文参数,然后将其传递给比较函数:With the C function
qsort()
, no, there is no way to pass the length to your comparison function without using a global variable, which means it can't be done in a thread-safe manner. Some systems have aqsort_r()
function (r stands for reentrant) which allows you to pass an extra context parameter, which then gets passed on to your comparison function:是否存在不能以空终止缓冲区的原因?
如果没有,由于您使用的是 C++,您可以编写自己的函数对象:
Is there a reason you can't null-terminate your buffers?
If not, since you're using C++ you can write your own function object:
您可以将缓冲区指针 + 长度打包到一个结构中,并将该结构的指针作为
void *
传递吗?Can you pack your buffer pointer + length into a structure and pass a pointer of that structure as
void *
?您可以使用如下 hack:
首先将其调用为
buffcmp(&bsize, NULL)
,然后将其作为比较函数传递给qsort
。当然,您可以通过添加更多
if
语句,使比较在 buffcmp(NULL, NULL) 等情况下表现得更自然。You could use a hack like:
which you would first call as
buffcmp(&bsize, NULL)
and then pass it as the comparison function toqsort
.You could of course make the comparison behave more naturally in the case of
buffcmp(NULL, NULL)
etc by adding moreif
statements.您可以使用仿函数(将长度赋予仿函数的构造函数)或 Boost.Lambda(就地使用长度)。
You could functors (give the length to the functor's constructor) or Boost.Lambda (use the length in-place).
我不清楚你在问什么。 但我会尝试,假设
这相当于代码:
现在如果您控制缓冲区的分配,您可以
使用 strcmp 替换并继续。 即使您不控制缓冲区的填充,这也是可能的。
如果您必须忍受其他人交给您的缓冲区,您可以
ary
的定义。sort_r
或家庭滚动解决方案(我确实推荐将其作为学生的练习,但在现实生活中不推荐)。 无论哪种情况,额外的数据都可能是指向缓冲区末尾的指针。I'm not clear on what you're asking. But I'll try, assuming that
That is code equivalent to:
Now if you control the allocation of the buffer, you could substitute
and go ahead using strcmp. This may be possible even if you don't control the filling of the buffer.
If you have to live with a buffer handed you by someone else you can
ary
in the above code.sort_r
as suggested by Adam, or a home-rolled solution (which I do recommend as an exercise for the student, and don't recommend in real life). In either case the extra data is probably a pointer to the end of the buffer.memcmp
应该在第一个不相等的字节处停止,因此长度应该很大,即到缓冲区的末尾。 那么它返回零的唯一方法是它确实到达缓冲区的末尾。(顺便说一句,我自己倾向于合并排序。它稳定且表现良好。)
memcmp
should stop on the first byte that is unequal, so the length should be large, i.e. to-the-end-of-the-buffer. Then the only way it can return zero is if it does go to the end of the buffer.(BTW, I lean toward merge sort myself. It's stable and well-behaved.)