很多地方都遇過排列組合,比如計算問題的規模,資料的大小,佔用磁碟空間多少等。
原理部分借鑒網上一篇文章,道理已經說的很清楚就不重複了。
(1) 全排列:
全排列表示把集合中元素的所有按照一定的順序排列起來,使用P(n, n) = n!表示n個元素全排列的個數。
例如:{1, 2, 3}的全排列為:
123;132;
213;231;
312;321;
共6個,即3!=3*2*1=6。
這個是怎麼算出來的呢?
首先取一個元素,例如取出了1,那麼就還剩下{2, 3}。
然後再從剩下的集合中取出一個元素,例如取出2,那麼還剩下{3}。
以此類推,把所有可能的情況取一遍,就是全排列了,
#include <iostream>#include <vector>#include <vector>using namespace std;#define MAX_SIZE 5void swap(vector<int> &lst, int i, int j){ int tmp = lst[i]; lst[i] = lst[j]; lst[j] = tmp;}void perm(vector<int> &lst, int start, int end, vector<vector<int> > &dst){ if (start >= end) { dst.push_back(lst); } else { for (int i=start;i<end;i++) { swap(lst, start, i); perm(lst, start+1, end, dst); swap(lst, start, i); } }}intmain(int argc, const char *argv[]){ vector<vector<int> > dst; vector<int> lst; for(int i=0;i<MAX_SIZE;i++) { lst.push_back(i); } perm(lst, 0, MAX_SIZE, dst); cout << "len " << (int)dst.size() << endl; int i=0; for(vector<vector<int> >::iterator lt=dst.begin();lt<dst.end();lt++){ cout << i << ": "; for(vector<int>::iterator it=(*lt).begin();it < (*lt).end(); it++) { cout << *it; } cout << endl; i++; } cout << endl; return 0;}
排列計算公式
從n個不同元素中,任取m(m≤n)個元素按照一定的順序排成一列,叫做從n個不同元素中取出m個元素的一個排列;從n個不同元素中取出m(m≤n)個元素的所有排列的個數,叫做從n個不同元素中取出m個元素的排列數,用符號 p(n,m)表示.
p(n,m)=n(n-1)(n-2)……(n-m+1)= n!/(n-m)!(規定0!=1).
附上計算公式的代碼:
#include <iostream>#include <cstdio>#include <cstdlib>using namespace std;long factorial(int num){ long result=1; for(int i=1;i<=num;i++){ result*=i; } return result;}long pnm(int num, int len){ return factorial(num)/len*factorial(num-len);}intmain(int argc, const char *argv[]){ if (argc < 2) { printf("usage:%s num", argv[0]); return 0; } //printf("%s", argv[1]); //return 0; int num=atoi(argv[1]); long result = factorial(num); cout << "factorial result :" <<result<<endl; cout << "pnm result :" << pnm(10, 9)<<endl; return 0;}
組合部分待續。。
參考:
http://www.cnblogs.com/autosar/archive/2012/04/08/2437799.html
http://www.ixuela.com/shuxue/jiangjie/18300.html
http://www.360doc.com/content/10/0426/08/1217123_24908058.shtml