【问题标题】:Why can't I generate all permutations with std::next_permutation?为什么我不能使用 std::next_permutation 生成所有排列?
【发布时间】:2021-01-22 20:12:49
【问题描述】:

我正在尝试使用 C++14 STL 中的 std::next_permutation 获取二进制值的所有排列(在本例中,由整数 0 和 1 表示)。

但是,我确实认为我在这种方法中发现了一个错误。
如果向量在其一个或多个零,则一个无法获得向量的所有排列。

例如,让我们考虑向量std::vector<int> a = {1,0,0}std::next_permutation 发现的唯一排列是 {(1 0 0)},而存在三种可能的排列 {(1 0 0), (0 1 0), (0 0 1)}

这是一个错误吗?如果有,我在哪里可以举报?

您可以在 C++ shell here 中访问我的代码。它也显示在下面。

#include <iostream>
#include <vector>
#include <algorithm>

int main() {

  std::vector<int> a = {1,0,0,0};
  std::vector<int> b = {0,0,0,1};

  std::cout << "Permutations of a" << std::endl;
  do {
    for (int i = 0; i < a.size(); i++) {
      std::cout << a[i];
    }
  std::cout << std::endl;
  } while (std::next_permutation(a.begin(), a.end()));
  
  
  std::cout << std::endl << "Permutations of b" << std::endl;
  
  do {
    for (int i = 0; i < b.size(); i++) {
      std::cout << b[i];
    }
    std::cout << std::endl;
  } while (std::next_permutation(b.begin(), b.end()));
  exit(0);
}

输出:

Permutations of a
1000

Permutations of b
0001
0010
0100
1000

【问题讨论】:

  • 在确定这是一个错误之前,您是否阅读过任何文档?
  • 如果next_permutation 在最后一次排列后没有停止,那么您的循环将永远不会结束,因此它确实是一个功能。
  • 不要仅仅通过名字来猜测函数的作用,它可能经常出错(不幸的是)

标签: c++ stl c++14 permutation


【解决方案1】:

来自reference

将范围 [first, last) 排列到下一个排列中,其中所有排列的集合按字典顺序相对于 operator

因此,遍历排列只会为您提供从初始范围按字典顺序递增的序列。

请注意,参考页面底部的示例在初始范围上做了一个std::sort,以便生成所有排列。

【讨论】:

  • 链接的网页不是“参考”,即使它被这样称呼(尽管它是一个非常有用的页面)。
  • @Acorn 我通常使用“reference”,甚至是“wording”/“rules”/etc,不区分链接是指向eel.is/c++draft还是cppreference.com(显然只有前者用于language-lawyer 问题)。您认为需要从文本中清楚它是哪一个吗?
  • 这没什么大不了的,但总的来说,我避免将任何网络称为“参考”,更不用说 the 参考(当然,除非它是实际参考)。新的 C++ 程序员可能会将其误认为是许多其他语言的官方文档。有像 w3schools 这样臭名昭著的例子......此外,cppreference 它是一个任何人都可以(可以?)编辑的维基。
【解决方案2】:

来自 C++20 标准 [alg.permutation.generators]:

效果: 采用由范围[first, last) 定义的序列并将其转换为下一个排列。通过假设所有排列的集合相对于compproj 按字典顺序排序,可以找到下一个排列。如果不存在这样的排列,则将序列转换为第一个排列;也就是升序排序的。

你的a 已经是最后一个排列,所以函数返回false。就像b 达到相同状态时一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 2023-04-09
    • 2017-11-12
    • 2018-10-01
    相关资源
    最近更新 更多