我对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:
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() );
}

我的功能比需要的要复杂,但是我想确保自己了解发生了什么。

这是打印此类集的典型输出:
每个小组都有一行,在该行中我先打印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排序(这是每行的第一行),而事实并非如此。

然后我在输出中有一些重复的行(没有出现在上面的示例中,但是出现在完整的输出中)。我想我有重复的事实并不奇怪,因为它似乎对订单感到困惑。

我猜答案很明显,但我看不到。任何帮助,将不胜感激!

最佳答案

您的bool operator <( const Clique &rhs ) const错误,因为它不遵守严格的顺序。

它可能只是:

bool operator <(const Clique& rhs) const
{
    return std::tie(b, e, X) < std::tie(rhs.b, rhs.e, rhs.X);
}

10-04 20:48