含重复元素的全排列如果直接用前面的简单递归会产生重复输出
所以没有重复输出的全排列需要用状态转移来做
假设1 2 3 4 5 5 6
这几个数
它的下一个状态为 1 2 3 4 5 6 5
1234655
1235456
......
这样的规律是
(1)从最后面起找到一个降序排列的子序列,记子序列开头为index
(2)在子序列找到离v[index-1]最近的且大于它的数,两者交换
(3)对交换后元素的子序列进行升序排列
(4)回到(1)
代码如下:
/*
ID: ranyang1
PROG:
LANG:C++
*/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#define MaxN 1000
#define Maxnumber 100000
using namespace std;
ofstream fout("text.out");
ifstream fin("text.in");
void VecPrint(vector<int> v){
vector<int>::iterator i;
for (i=v.begin();i!=v.end();i++)
{
fout<<*i<<' ';
}
fout<<endl;
}
int findthedownseq(vector<int> v){
int i;
for (i=v.size()-1;i>0;--i)
{
if (v[i-1]<v[i])
{
return i;
}
}
return i;
}
int findplusindex(vector<int> v,int index)
{
int valuetemp=v[index-1];
for (int i=v.size()-1;i>=index;i--)
{
if (v[i]-valuetemp>0)
{
return i;
}
}
return -1;
}
void Permutate(vector<int> v){
VecPrint(v);
int index=findthedownseq(v);
if (index)
{
int plusindex=findplusindex(v,index);
swap(v[index-1],v[plusindex]);
vector<int>::iterator p=v.begin()+index;
sort(p,v.end());
Permutate(v);
}
}
int main()
{
int num;
fin>>num;
vector<int> vint(num);
for (int i=0;i<num;i++)
{
fin>>vint[i];
}
sort(vint.begin(),vint.end());
// sort(0,vint.size()-1,vint);
Permutate(vint);
// VecPrint(vint);
return 0;
}