【发布时间】:2016-12-09 08:58:27
【问题描述】:
我对 C++ 很陌生(但对 C 很了解),所以我可能遗漏了一些明显的东西。
TLDR:我使用存储元素两次的 std::set,这绝对不是我想要的。
长篇大论: 我已经定义了一个类 Clique,我需要将这个类的元素存储在一个集合中,所以我为 Clique 定义了
class Clique{
public :
int b;
int e;
int l;
std::set<int> X;
bool operator <( const Clique &rhs ) const
{
if( b < rhs.b)
return true;
if( e < rhs.e)
return true;
if( X.size() < rhs.X.size() )
return true;
std::set<int>::iterator itX = X.begin();
std::set<int>::iterator itrhs = rhs.X.begin();
// both sets have same size, need only to check end for one of them
while( (*itX == *itrhs) && ( itX != X.end() ) ){
++itX;
++itrhs;
}
if( itX == X.end() ){
//both sets are equal
return false;
}
else
return ( *itX < *itrhs );
}
void print_clique(FILE *F) const ;
};
(我不确定集合比较是如何进行的,所以我编写了一个例程,先按大小比较它们,然后逐个元素比较)。
现在我想将 Clique 元素存储在一个集合中,这就是问题出现的地方。 我的 std::set (1) 似乎没有按照我定义的顺序存储 Clique 元素; (2) 存储同一个 Clique 的多个副本
我写了一个函数来打印一组 Clique:
void print_cliqueset(std::set<Clique> mySet){
int setsize = 0;
std::set<Clique>::iterator it = mySet.begin();
Clique cur_c = *it;
Clique prev_c = *it;
while( it != mySet.end() ){
// for( std::set<Clique>::iterator it = mySet.begin(); it != mySet.end(); ++it ){
it->print_clique(stdout);
setsize ++;
++it;
if( it != mySet.end() ){
cur_c = *it;
assert ( prev_c < cur_c);
gassert( prev_c.b <= cur_c.b );
prev_c = *it;
}
}
assert( setsize == mySet.size() );
}
我的功能比需要的更复杂,但我想确保我理解发生了什么。
以下是打印此类集合的典型输出: 每个 Clique 都有一行,我首先打印 b,然后是 e,然后是集合 X 中的元素。
6829 9716 1 2 3 5 8 9 10
6792 9687 1 2 3 7 8 9 10
606 6531 1 2 3 5 6 7 8 9
6829 9687 1 2 3 5 7 8 9 10
410 9951 2 6
484 9805 1 2 4 6
494 9805 2 4 6 10
506 9805 1 2 5 6
484 9821 1 2 4
484 9871 2 3 4 6
506 9821 1 2 5
484 9802 1 2 3 4 6
486 9805 1 2 4 6 9
486 9802 1 2 3 4 6 9
507 9802 1 2 3 4 6 9 10
502 9802 1 2 3 4 6 10
506 9802 1 2 3 5 6
507 9806 1 2 4 9 10
507 9805 1 2 5 6 9
527 9806 1 2 5 9 10
正如我们所见,派系根本没有按照我定义(或想要定义)的顺序排序。它们应该首先按成员 b 排序(即每行的第一个),而事实并非如此。
然后我在输出中有一些重复的行(没有出现在上面的示例中,但出现在完整的输出中)。我想我有重复的事实并不奇怪,因为它似乎对顺序感到困惑......
我想答案是相当明显的,但我看不到它。任何帮助将不胜感激!
【问题讨论】:
-
您使用哪种 C++ 标准?解决方案的复杂性取决于此。
-
您的比较器需要遵循例如指定的 等价关系 this
std::setreference. -
顺便说一句,成员
int l;未进行比较。