使用std :: sort和std :: next_permutation

时间:2013-08-01 19:17:24

标签: c++ algorithm

我有以下代码,我编写并完美地工作。我只是很难理解它为什么会起作用。更具体地说,为什么我们必须首先对数组进行排序才能使用std :: next_permutation,它是否可以从任何配置开始?

困扰我的部分是我不明白我们为什么要写作 排序(边,边+ 3)和next_permutation(边,边+ 3)为什么是“+3”!因为我在数组中有三个元素?如果我使用任意数量的元素会怎么样?

bool valid(int sides[], ofstream &outfile)
{
  int i = 0;
  for(; i < 3; i++) {
    if(sides[i] <= 0) {
      outfile << "This is not a valid triangle because it\n "
              << "contains negative sides or contains a\n"
              << "side length of 0\n\n";
      return false;
    }
  }

  do{
    std::sort(sides,sides+3);
    if(sides[0] + sides[1] > sides[2])
      ;
    else{
      outfile << "This is not a valid triangle because "
              << sides[0] << " + " << sides[1]
              << " is not greater than " << sides[2];
      return false;
    }
  }while(std::next_permutation(sides,sides+3));

  return true;
}

3 个答案:

答案 0 :(得分:2)

欧几里德几何学告诉我们:
双方的总和始终大于剩余的一方

  

让我们拿一个三角形ABC   AB = 3
  BC = 5
  AC = 4

std :: sort会将边排序为升序。这样阵列首先会包含短边。

  排序后

  side [0] = AB = 3
  方[1] = AC = 4
  side [2] = BC = 5

std :: next_permutation返回下一个可能的sides组合。例如:

  

AC = 3
  BC = 5
  AB = 4

一个简单的例子:

#include <iostream>     // std::cout
#include <algorithm>    // std::next_permutation, std::sort

int main () {
  int myints[] = {1,2,3};

  std::sort (myints,myints+3);

  std::cout << "The 3! possible permutations with 3 elements:\n";

  while ( std::next_permutation(myints,myints+3) )
  {
    std::cout << myints[0] << ' ' << myints[1];
    std::cout << ' ' << myints[2] << '\n';
  }

  std::cout << "After loop: " << myints[0] << ' ';
  std::cout << myints[1] << ' ' << myints[2] << '\n';

  return 0;
}

进一步阅读:http://www.cplusplus.com/reference/algorithm/next_permutation/

答案 1 :(得分:2)

std :: next_permutation文档

  

将范围转换为下一个排列重新排列元素中的元素   范围[第一个,最后一个]进入下一个按字典顺序排列更大   排列。

所以,除非你开始排序,否则你不会经历所有排列

所以,如果你从

开始
  

1,2,3

最后的排列将是

  

3,2,1

如果你从

开始
  

3,1,2

只会找到另外一个排列,而不是全部

答案 2 :(得分:1)

在不对其进行排序时,请查看std::next_permuntation的结果:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

enum class sort { no, yes };

void show_permutations(std::string s, sort option) {
  if (sort::yes == option) {
    std::sort(std::begin(s), std::end(s));
  }

  do {
    std::cout << s << '\n';
  } while (std::next_permutation(std::begin(s), std::end(s)));
}

int main() {
  show_permutations("3412", sort::yes);

  std::cout << "Now without sorting...\n";

  show_permutations("3412", sort::no);
}

检查输出以查看是否有任何有趣的内容:

1234
1243
1324
1342
1423
1432
2134
2143
2314
2341
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4213
4231
4312
4321
Now without sorting...
3412
3421
4123
4132
4213
4231
4312
4321

在没有排序的情况下创建的序列与通过排序创建的序列的最末端相同。这对输入的排序重要性意味着什么?


如果将排序代码放在循环中,您认为会发生什么?

void show_permutations(std::string s, sort option) {
  do {

    if (sort::yes == option) {
      std::sort(std::begin(s), std::end(s));
    }

    std::cout << s << '\n';
  } while (std::next_permutation(std::begin(s), std::end(s)));
}

请注意,您的程序会对next_permutation循环内的三角形边进行排序,类似于此代码对循环内的输入字符串进行排序。