排列组合实现

来源:互联网 发布:淘宝老店换类目 开新店 编辑:程序博客网 时间:2024/05/20 16:42

http://www.zxbc.cn/html/20070424/7348.html

来源 算法来源与互联网

组合算法  
  本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标  
  代表的数被选中,为0则没选中。    
  首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。    
  然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为  
  “01”组合,同时将其左边的所有“1”全部移动到数组的最左端。    
  当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得  
  到了最后一个组合。    
  例如求5中选3的组合:    
  1   1   1   0   0   //1,2,3    
  1   1   0   1   0   //1,2,4    
  1   0   1   1   0   //1,3,4    
  0   1   1   1   0   //2,3,4    
  1   1   0   0   1   //1,2,5    
  1   0   1   0   1   //1,3,5    
  0   1   1   0   1   //2,3,5    
  1   0   0   1   1   //1,4,5    
  0   1   0   1   1   //2,4,5    
  0   0   1   1   1   //3,4,5  

1元 2元 5元 10元 20元 50元 100元自由组合可以组成的数目的多少,并且分别为多少?

根据上次中网友给的一个方法,实现上面问题的代码为:

#include<iostream>
#include <iomanip>
using namespace std;

#define  M  7

int data[M] = {0}; // set tags
int money_style[7] = {1,2,5,10,20,50,100};
int num = 0;
void initialization(int n)
{
 for(int i = 0; i < n; i++)  //set position as tag 1
 {
  data[i] = 1;
 } 
 for(i = n; i < M; i++)      //null position as tag 0
 {
  data[i] = 0;
 } 
}

void getData()

 int sum = 0;
 cout <<left;
 cout<<setw(10)<<++num;
 for(int i = 0; i < M; i++)
 {
  if (data[i]==1)          //if has tag == 1 get position
  {
   //cout<<i+1;
   cout <<left;
   cout<<setw(6)<<money_style[i];
   sum+= money_style[i];  
  }  
 }
    cout <<right;
    cout<<setw(15);
    cout <<"" <<sum<<"元"<<endl;
}
void reSet(int before)
{
 int count = 0;
 for(int i = 0; i < before; i++)//get number of tag 1
 {
  if(data[i]==1)
   count++;
 } 
 for(int j = 0; j < count; j++)  //set tag 1 from start position data[0]
 {
  data[j] = 1;
 }
 for( ; j < before; j++)   //others set tag 0
 {
  data[j] = 0;
 }
}

void m_select_n()
{
 int i = 0;

 while(1)
 {
  int bfind = false;
  if(data[i]== 1 && data[i+1] == 0) //get  [][][1][0][][][][]
  {
   data[i] = 0;
   data[i+1] =1;    //set [1][0]-> [0][1]
   bfind = true;
   reSet(i);        //reset data[] from i position 
   getData();
   i = -1;          //start from i= 0 because  i++ =0
  }
  i++;              //i++ if i =-1 then start form begin i =0
  if(i == M-1)      //if i(0,1,2,3,4,5,6) = 6 ,then finished
   break;
 }
}

int main()
{
 for(int i = 1; i < M+1; i++) //from 1 to 7
 {
  initialization(i);
  getData();
  m_select_n();
 }
 return 0;
}