利用字典序生成下一個排列和組合的方法
阿新 • • 發佈:2019-02-04
先介紹生成排列的方法最簡單的方法是用STL自帶的next_permutation() 引數為要生成下一個排列的區間 利用字典序方法(其實上面這個函式就是用這個方法生成下一個排列的)先說下方法吧,以排列P1,P2,P3...Pn為例1 先從又右向左找到第一個滿足Pi-1<Pi的i2 再從右向左找第一個比Pi-1大的數,假設是Pk3 交換Pi-1與Pk,重新排列pi-1之後的數(不包含Pi-1)
int n, p[10]; cin >> n; for (int i = 0; i < n; i++) cin >> p[i]; sort(p, p + n); do { for (int i = 0; i < n; i++) cout << p[i]; cout << endl; } while (next_permutation(p, p + n)); //若已經是最後一個排列則返回false這個函式還可以接受比較函式,預設是小於號
生成排列數這兩種方法就足夠了,建議使用第一種,簡單好用對於如何生成集合S={1,2...n)的r組合,直接參考部落格程式碼連結下面介紹如何生成集合S={1,2...n)的所有子集int n, p[10]; cin >> n; for (int i = 0; i < n; i++) cin >> p[i]; sort(p, p + n); while (1) { for (int i = 0; i < n; i++) cout << p[i]; cout << endl; int i = n - 1; while (i > 0 && p[i - 1] > p[i]) i--; if (i == 0) break; //i==0說明已經是最後一個排列 int j; for (j = n - 1; j >= i; j--) if (p[j] > p[i - 1]) break; swap(p[i - 1], p[j]); sort(p + i, p + n); }
節省時間,並沒有講述原理,想了解的可以百度
12void print_subset(int n, int *A, int cur) { //增量構造法 for (int i = 0; i < cur; i++) cout << A[i] + 1; //輸出 puts(""); int s = cur ? A[cur - 1] + 1 : 0; //確定當前元素最小可能值 for (int i = s; i < n; i++) { A[cur] = i; print_subset(n, A, cur + 1); //遞迴構造子集 } } int main() { int n, a[10]; cin >> n; //n是集合元素的個數 print_subset(n, a, 0); system("pause"); }
void print_subset(int n, int *A, int cur) { //位向量法
if (cur == n) {
for (int i = 0; i < cur; i++)
if (A[i]) printf("%d", i + 1);
puts(""); return;
}
A[cur] = 1;
print_subset(n, A, cur + 1);
A[cur] = 0;
print_subset(n, A, cur + 1);
}
int main()
{
int n, a[10]; cin >> n; //n是集合元素的個數
print_subset(n, a, 0);
system("pause");
}
3 (最簡練)void print_subset(int n, int s) { //二進位制法
for (int i = 0; i < n; i++)
if (s&(1 << i)) printf("%d", i + 1);
printf("\n");
}
int main()
{
int n, a[10]; cin >> n; //n是集合元素的個數
for (int i = 1; i < (1 << n); i++)
print_subset(n, i);
system("pause");
}