全排列_问题(含重复元素)

来源:互联网 发布:mysql新建数据库 编辑:程序博客网 时间:2024/04/28 10:58

含重复元素的全排列如果直接用前面的简单递归会产生重复输出

所以没有重复输出的全排列需要用状态转移来做

 

假设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;
}

原创粉丝点击