【问题标题】:next_permutation with custom comparer function c++next_permutation 与自定义比较器函数 c++
【发布时间】:2015-06-22 01:33:18
【问题描述】:

我正在为我的 next_permutation 函数使用自定义比较器函数,但我不明白为什么会出现错误:

Expression: invalid operator<

我希望我的函数至少能在函数体中受到这些限制,但不断出错:

bool mycomp(int i, int j)
{
    return (((i < 0) && (j > 0)) || ((i > 0) && (j < 0)));
};

但是当我这样做时,它工作正常:

bool mycomp(int i, int j)
{
    return (((i < 0) && (j > 0)));
};

我还想添加另一个限制,但不知道如何。 这里是 next_permutation 函数的相关代码:

int counter, size, *guests;
for (int i = 2; i <= 9; i++)
{
    size = i * 2;
    counter = 1;
    guests = new int[size];
    for (int j = 0; j < size; j += 2)
    {
        guests[j] = counter;
        guests[j + 1] = 0 - counter;
        ++counter;
    }
    sort(guests, guests + size);
    counter = 0;
    while (next_permutation(guests, guests + size, mycomp))
    {
        ++counter;
    }
}

我也明白有严格的弱排序要求。在阅读了它之后,我理解了它的要点,但不确定它究竟如何适用于这种情况。提前谢谢你。

【问题讨论】:

  • 您认为自定义比较器功能有什么作用?您认为使用给定的自定义比较器意味着是什么?你对“限制”的使用对我来说是一个危险信号。
  • 使用你的第一个函数没有错误:现场演示:coliru.stacked-crooked.com/a/8abe254b696f6df8
  • @Stephen :它默默地失败了。 OP 有机会获得一个调试断言来检查其比较器的有效性
  • @Yakk 那么我想我不知道自定义比较器的用途。我会试着查一下。在这种情况下,我认为它是用来限制排列以最小化找到的排列数量。
  • @Yakk 自定义比较器在 next_permutation 函数中做了什么?

标签: c++ permutation


【解决方案1】:

您的编译器试图(通过运行时断言)告诉您比较器无效。它是无效的,因为它不尊重严格的弱订购合同,至少有两个原因:

1) 它不是反对称(即 f(x, y) 蕴含 !f(y, x)):

std::cout << mycomp(2, -3) << '\n';
std::cout << mycomp(-3, 2) << '\n';

输出:

true
true

2) 它不是传递的(即 f(x, y) 和 f(y, z) 隐含 f(x, z) ):

std::cout << mycomp(2, -3) << '\n';
std::cout << mycomp(-3, 2) << '\n';
std::cout << mycomp(2, 2) << '\n';

输出:

true
true
false
false

Demo

您可能需要重新考虑您的问题,以及在进行排列时您真正希望如何对元素进行排序。

【讨论】:

  • 你的例子并不能证明它的反对称。你应该选择f(2,-3)
  • @Barry 感谢您的回复,但您的输出对于 2) 似乎不正确。我会思考你的答案并尝试理解它。
【解决方案2】:

排列是关于排序。默认顺序是1&lt;2&lt;3&lt;4&lt;5&lt;6 等等——你习惯的顺序。

自定义比较器可让您设置不同于默认值的排序。

这在许多情况下都很有用。

对于一个玩具示例,您可以将所有偶数设置为大于所有奇数 -- 1&lt;3&lt;5&lt;7&lt;...&lt;0&lt;2&lt;4&lt;6&lt;8&lt;...

利用std::tuple 的示例实现:

std::tuple<bool,unsigned> myhelper( unsigned x ) {
  return std::make_tuple( !(x%2), x );
}
bool myorder( unsigned lhs, unsigned rhs ) {
  return helper(lhx)<helper(rhs);
}

对于没有严格弱排序运算符&lt; 的类型,它允许您提供一个。复数可以按字典顺序或量值排序:量值排序不是严格的弱排序,让&lt; 成为字典顺序会令人惊讶。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多