【问题标题】:How can I sort a list when the sorting criterion requires an extra variable? C++当排序标准需要额外变量时,如何对列表进行排序? C++
【发布时间】:2010-12-06 04:00:15
【问题描述】:

这是一个任务,所以我会故意笼统地说。我的问题与我已经做出的实施决策有关——也许它们不是好的决策。

我有一个指向结构的指针列表,例如list<MyStruct*> bob; 在某一时刻,我需要按目标的数据成员之一对这些指针进行排序,而我可以很容易地做到这一点

bool sortbyarrival(const MyStruct* a, const MyStruct* b) {
return a->arrival < b->arrival;
}

然后调用bob.sort(sortbyarrival); 效果很好。

现在我需要在其他地方按不同的标准进行排序,这涉及程序中的计数器。我需要像return counter*a-&gt;arrival &lt; counter*b-&gt;arrival; 这样的东西,但我认为,我刚才描述的方式是我知道如何进行排序的唯一方法,而且我不知道如何将我的计数器作为附加参数传递。如何对这个指针列表进行排序?

ETA:计数器只是 main 中的一个变量。所以理想情况下我可以打电话给bob.sort(sortbyratio, counter);sort(bob.begin(), bob.end(), sortbyratio, counter);

【问题讨论】:

  • list 是 STL 的 std::list,还是其他类型?
  • 我很困惑。两边乘以counter 有什么作用?
  • 我想我把这个任务伪装得太多了。我正在尝试按惩罚比率对某些内容进行排序,因此在真正的问题中,我将当前时钟时间除以结构的成员以得出一个比率,我想以此对列表进行排序。
  • 对于一个正常数 k,(k / x) &lt; (k / y) 当且仅当 y &lt; x(假设没有零,并且 x 和 y 具有相同的符号。如果它们具有不同的符号,则负数是较小的有或没有互惠)。所以只需按相反的顺序排序,并为自己节省一些浮点废话。这是因为对于正 k,f(x) = k/x 是 0 两边的单调递减函数,在 0 处不连续。
  • @onebyone:你说得对,这没有任何意义。你让我回过头来更仔细地研究这个问题。它实际上是 (k - 我差点忘记的东西) / x。感谢您意识到这一点并让我检查。

标签: c++ sorting list


【解决方案1】:

类似于 ltcmelo 的示例,但如果对象本身不包含计数器:

struct sort_with_counter {
    sort_with_counter(const double d): counter(d) {}

    bool operator()(const MyStruct* a, const MyStruct* b) {
        return(counter*a->arrival < counter*b->arrival);
    }

    const double counter;
};

mylist.sort(sort_with_counter(5.0));

如果您的计数器是这样的外部变量,尽管它不会影响排序(至少如果它是肯定的 - 谢谢大家!) - 所以这实际上可能根本没有必要(或者我可能误解了你的意思)重新追求?)。但在其他情况下,这是一种有用的技术。

【讨论】:

  • “它不会影响订购” - 请参阅我答案的最后一行 :-)
  • 谢谢 - 我认为这一点仍然很重要(这将是一种颠倒排序顺序的奇怪方式,我认为这不是 OP 的意图),但重要的是要正确: )
  • 谢谢,这对我没有很好描述的问题非常有效。对不起,我没有早点回来,我正试图把整个事情都上交!
【解决方案2】:

创建一个函子,并将额外的值存储在函子对象中:

struct CompareByCounter {
    CompareByCounter(int c) : counter(c) {}
    bool operator()(const MyStruct *lhs, const MyStruct *rhs) {
        return (counter * lhs->arrival) < (counter * rhs->arrival);
    }
private:
    int counter;
};

// sort ascending
bob.sort(CompareByCounter(1));
// sort descending
bob.sort(CompareByCounter(-1));

【讨论】:

    【解决方案3】:

    只需创建一个函数对象,一个带有 operator() 重载的类/结构,它会为您做正确的事情。在这种情况下,考虑到额外的变量。然后,将它的一个实例传递给 sort 方法。

    
    struct my_comparison : binary_function<MyStruct const*, MyStruct const*, bool> 
    {
      bool operator()(MyStruct const* a, MyStruct const* b) 
      { 
        return (a->counter * a->arrival) < (b->counter * b->arrival);
      }
    };
    
    //Use it this way.
    my_comparison comp;
    
    //Set the arrival and counter data in instance comp.
    /* ... */
    
    //Now, pass it to the list.
    bob.sort(comp);
    

    编辑:我刚刚注意到您有一个指针列表,所以我对结构进行了一些更改。

    【讨论】:

    • 我不确定这是否可行——counter 不是你在这个例子中展示的结构的成员,它只是 main 中的另一个变量。我可以将其作为非二进制重载来执行,例如 bool operator() (MyStruct const& a, MyStruct const& b, int somecounter) 等吗?那我怎么称呼它?谢谢。
    • 所以只需在 MyStruct 中创建一个副本或引用或指向它的指针。或者使用另一种包含计数器的类型。这行得通吗?
    猜你喜欢
    • 2012-06-26
    • 2015-06-01
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 2017-12-05
    • 2021-10-10
    相关资源
    最近更新 更多