我正在尝试对concurrent_vector类型进行排序,其中hits_object
为:
struct hits_object{
unsigned long int hash;
int position;
};
以下是我正在使用的代码:
concurrent_vector<hits_object*> hits;
for(i=0;...){
hits_object *obj=(hits_object*)malloc(sizeof(hits_object));
obj->position=i;
obj->hash=_prevHash[tid];
hits[i]=obj;
}
现在我填写了一个名为concurrent_vector<hits_object*>
的{{1}}。
但是我想在position属性上对这个concurrent_vector进行排序!!!
以下是典型命中对象内部的示例:
hits
我想根据第一列(0 1106579628979812621
4237 1978650773053442200
512 3993899825106178560
4749 739461489314544830
1024 1629056397321528633
5261 593672691728388007
1536 5320457688954994196
5773 9017584181485751685
2048 4321435111178287982
6285 7119721556722067586
2560 7464213275487369093
6797 5363778283295017380
3072 255404511111217936
7309 5944699400741478979
3584 1069999863423687408
7821 3050974832468442286
4096 5230358938835592022
8333 5235649807131532071
类型的“位置”)对此进行排序。第二列是int
类型的“哈希”。
现在我尝试了以下操作:
unsigned long int
其中std::sort(hits.begin(),hits.end(),compareByPosition);
定义为:
compareByPosition
但是当我放入int compareByPosition(const void *elem1,const void *elem2 )
{
return ((hits_object*)elem1)->position > ((hits_object*)elem2)->position? 1 : -1;
}
请帮忙!
答案 0 :(得分:7)
你的compare函数需要返回一个布尔值0或1,而不是整数1或-1,它应该有一个强类型签名:
bool compareByPosition(const hits_object *elem1, const hits_object *elem2 )
{
return elem1->position < elem2->position;
}
您看到的错误是由于std::sort
将从comp函数返回的所有非零解释为true
,这意味着左侧小于右侧。 / p>
注意:由于与sbi和Mike Seymour的对话,此答案经过大量编辑。
答案 1 :(得分:5)
在不知道concurrent_vector
是什么的情况下,我无法确定是什么导致了细分错误。假设它与std::vector
类似,则需要使用hits.push_back(obj)
而不是hits[i] = j
填充它;你不能使用[]
来访问向量末尾之外的元素,或者根本不能访问空向量。
比较函数应该等于a < b
,返回一个布尔值;它不是C风格的比较函数,返回负数,正数或零。此外,由于sort
是一个模板,因此不需要C风格的void *
参数;一切都是强类型的:
bool compareByPosition(hits_object const * elem1, hits_object const * elem2) {
return elem1->position < elem2->position;
}
此外,您通常不希望使用new
(当然也不会malloc
)来创建存储在向量中的对象;最简单和最安全的容器是vector<hits_object>
(以及一个比较器,它将引用而不是指针作为参数)。如果你真的必须存储指针(因为对象的复制费用很高而且不可移动,或者因为你需要多态性 - 这两者都不适用于你的例子),要么使用智能指针,如std::unique_ptr
,要么确保你{ {1}}一旦你完成了它们就行了。
答案 2 :(得分:5)
int (*)(void*, void*)
是C qsort()
函数的比较器。在C ++ std::sort()
中,比较器的原型是:
bool cmp(const hits_object* lhs, const hits_object* rhs)
{
return lhs->position < rhs->position;
}
std::sort(hits.begin(), hits.end(), &cmp);
另一方面,您可以使用std::pair
struct,默认情况下比较其第一个字段:
typedef std::pair<int position, unsigned long int hash> hits_object;
// ...
std::sort(hits.begin(), hits.end());
答案 3 :(得分:4)
传递给std::sort()
的第三个参数必须具有与operator<()
类似的签名和语义:
bool is_smaller_position(const hits_object* lhs, const hits_object* rhs)
{
return lhs->position < rhs->position;
}
当您将指针存储在向量中时,不能重载operator<()
,因为小于所有内置类型的指针。
在旁注: Do not use malloc()
in C++ ,请改用new
。另外,我想知道你为什么不使用 对象 而不是指针。最后,如果concurrent_vector
与std::vector
类似,则需要 明确地使其展开 以适应新对象。这就是您的代码的样子:
concurrent_vector<hits_object*> hits;
for(i=0;...){
hits_object obj;
obj.position=i;
obj.hash=_prevHash[tid];
hits.push_back(obj);
}
答案 4 :(得分:0)
这看起来不对:
for(i=0;...){
hits_object *obj=(hits_object*)malloc(sizeof(hits_object));
obj->position=i;
obj->hash=_prevHash[tid];
hits[i]=obj;
}
这里你已经基于'i'对数组进行排序,因为你将位置设置为i以及它成为命中的索引!
为什么使用malloc
,你应该使用new(/ delete)。然后,您可以为结构创建一个简单的构造函数来初始化hits_object
e.g。
struct hits_object
{
int position;
unsigned int hash;
hits_object( int p, unsigned int h ) : position(p), hash(h) {;}
};
然后写下来
hits_object* obj = new hits_object( i, _prevHash[tid] );
甚至
hits.push_back( new hits_object( i, _prevHash[tid] ) );
最后,您的比较函数应使用与其参数相同的数据类型
bool cmp( hits_object* p1, hits_object* p2 )
{
return p1->position < p2->position;
}