【问题标题】:Prev_permutation vs Next_permutation difficultyPrev_permutation vs Next_permutation 难度
【发布时间】:2012-09-01 19:33:03
【问题描述】:

我正在尝试一个示例程序来掌握 prev 和 next 排列之间的区别。但是,我的程序似乎无法正常工作。我通过询问数组中元素的数量来启动程序,然后用一个简单的 for 循环构建数组

for(i = 0; i < x; i++)
        ptr[i] = i;

cout << "Possible permuations using prev_permutation: " << endl;
    do{
        for(i = 0; i < x; i++)
            cout << ptr[i] << " ";
        cout << endl;
    } while(prev_permutation(ptr, ptr+x));

cout << "Possible permuations using next_permutation: " << endl;
do{
    for(i = 0; i < x; i++)
        cout << ptr[i] << " ";
    cout << endl;
} while(next_permutation(ptr, ptr+x));

当我使用包含 3 个元素 (0, 1, 2) 的样本运行代码时。 prev_permutation 给了我(0、1、2 等等)。然后 next_permutation 给我 (2, 1, 0)。但是,当我注释 prev_permutation 部分的代码时,当仅运行 next_permutation 时,我得到了集合(0、1、2)的正确 6 种不同排列。我似乎无法理解发生了什么。

【问题讨论】:

    标签: c++ algorithm sorting permutation probability


    【解决方案1】:

    prev_permutation 和 next_permutation 以字典(“字母”)顺序生成所有排列,一旦循环完成,它们就会返回 false(即,如果在第一个排列上调用 prev_permutation 或在调用 @987654325 之后@ 在最后一个)。

    发生的情况是,您按照字典顺序准备具有第一个排列的数组,然后调用prev_permutation。然而这是第一个,所以prev_permutation 将数组设置为最后一个排列并返回false,所以你退出循环。

    现在你进入next_permutation循环,但数组的当前内容是按字典顺序排列的最后一个排列,所以next_permutation将设置第一个并返回false。

    如果您删除 prev_permutation 部分,但 next_permutation 的循环将从第一个开始,因此它会在返回 false 之前正确生成所有 6 个排列。

    您可以考虑按顺序列出的所有排列并将当前配置作为此列表中的指针来可视化效果:

    0-1-2 << you start here
    0-2-1
    1-0-2
    1-2-0
    2-0-1
    2-1-0
    

    当调用next_permutation 时,你正在向下移动,当调用prev_permutation 时,你正在向上移动。当超出列表时,两个函数都会将指针移动到另一端并返回false 以通知您这一事实。

    如果您以prev 开头,则移动到2-1-0 并且函数返回false,然后您调用next 并且函数移动到0-1-2 并再次返回false。

    例如,使用两个零和三个一的排列代替0、1 和2,字典顺序是:

    0-0-1-1-1
    0-1-0-1-1
    0-1-1-0-1
    0-1-1-1-0
    1-0-0-1-1
    1-0-1-0-1
    1-0-1-1-0
    1-1-0-0-1
    1-1-0-1-0
    1-1-1-0-0
    

    所以要枚举所有这些,您需要从0-0-1-1-1 开始并使用next_permutation,或者您需要从1-1-1-0-0 开始并使用prev_permutation。

    在这种情况下,对最后一个1-1-1-0-0 调用next_permutation 将更改为第一个0-0-1-1-1 并返回false;以类似的方式在0-0-1-1-1 上调用prev_permutation 将更改为1-1-1-0-0 并由于翻转而返回false。

    【讨论】:

    • 我有一个简单的问题。当您说按字典顺序排列的列表时,它是指值吗?例如,我使用输入 (1 1 1 0 0) 运行了另一个 prev_permutation 示例。在我运行这个之后,我得到了所有可能的排列,但我不明白 prev 和 next 如何确定下一个排列将是什么。谢谢。
    • 字典顺序意味着要确定一个序列是在另一个之前还是之后,首先要比较第一个元素,如果它不同,那么第一个元素决定排序...如果两者都相等,那么你移动到第二个元素等等。在三个 1 和两个 0 的排列中,排列 (1 1 1 0 0) 是按字典顺序排列的最后一个排列,因此您可以从那里使用 prev_permutations 循环遍历所有排列。第一个是(0 0 1 1 1),您可以从它开始使用next_permutation 循环所有排列。
    • 感谢您的清理!是否可以通过 next_permutation 运行一组 (0 0 0 1 1),然后获得最终结果并运行 prev_permutation 以取回 0 0 0 1 1?所以,如果我将值存储在一个数组中,这个函数会改变数组的值吗?
    【解决方案2】:

    prev_permutation 和next_permutation 考虑的所有排列都有明确定义的字典顺序。您提供给他们的数组在该顺序中有一些位置。

    这就是为什么这两个函数都不能保证提供所有排列。

    如果您向prev_permutation 提供第一个可能的排列,就像您所做的那样,那么在它之前将没有排列。同样,如果您的数组定义为 (2, 1, 0),next_permutation 将不会提供任何新的排列。

    如果您需要某个集合的所有排列,您可能希望先sort 集合,然后使用next_permutation。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-25
      • 2022-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      • 1970-01-01
      相关资源
      最近更新 更多