平常需要全排列的时候,一般都是dfs然后字符串匹配啥的……今天看题解的时候突然发现了这个神器。
next_permutation()函数在c++的algorithm库里,作用是传入一个数组,输出这个数组的后一个排序。同样还有prev_permutation()输出前一个排序。这个“后一个”指的是,不存在另一个排序方案,字典序大于目前排序而小于将要输出的排序。(换句话说,把它的左右排列按字典序升序排序,输出当前状态的下一个)
next_permutation()是一个bool函数,当前序列不存在下一个排列时,函数返回false,否则返回true。
一个例子:(当然,也可以排序char类型,或处理一个string而不是数组)
#include <bits/stdc++.h> using namespace std; int arr[3] = {1, 2, 3}; int main(){ do{ cout << arr[0] << arr[1] << arr[2] << endl; }while(next_permutation(arr, arr+3)); return 0; //by MiserWeyte in cnblogs }
输出结果:
123 132 213 231 312 321
特别说明一下,以这段代码为例,如果执行循环前数组是按升序排列好的,则输出该数组的全排列,否则只是比初始状态大的一部分。
next_permutation()除了传入begin和end之外,也可以再传一个cmp函数进去。规则类似于sort(),cmp函数与重载小于号作用相同。
参考wzj792506536的博客中提到的poj 1256:Anagram。
Description
You are to write a program that has to generate all possible words from a given set of letters.
Example: Given the word "abc", your program should - by exploring all different combination of the three letters - output the words "abc", "acb", "bac", "bca", "cab" and "cba".
In the word taken from the input file, some letters may appear more than once. For a given word, your program should not produce the same word more than once, and the words should be output in alphabetically ascending order.Input
The input consists of several words. The first line contains a number giving the number of words to follow. Each following line contains one word. A word consists of uppercase or lowercase letters from A to Z. Uppercase and lowercase letters are to be considered different. The length of each word is less than 13.Output
For each word in the input, the output should contain all different words that can be generated with the letters of the given word. The words generated from the same input word should be output in alphabetically ascending order. An upper case letter goes before the corresponding lower case letter.Sample Input
3 aAb abc acbaSample Output
Aab Aba aAb abA bAa baA abc acb bac bca cab cba aabc aacb abac abca acab acba baac baca bcaa caab caba cbaaHint
An upper case letter goes before the corresponding lower case letter.
So the right order of letters is 'A'<'a'<'B'<'b'<...<'Z'<'z'.
(英语渣写一下大意:有n组数据,每组是一个字符串。对于每组数据,输出它按字母顺序(不是字典序,'A'<'a'<'B'<'b'<...<'Z'<'z')排序的全排列。)
利用自定义cmp解答:
#include <bits/stdc++.h> using namespace std; char str[20]; int cmp(const char &a, const char &b) { if(tolower(a) != tolower(b)) return tolower(a) < tolower(b); else return a < b; } int main() { int n; scanf("%d", &n); while(n--) { scanf("%s", str); sort(str, str+strlen(str), cmp); do { printf("%s ", str); } while(next_permutation(str, str+strlen(str), cmp)); } return 0; }