排列组合算法
来源:互联网 发布:音乐剪接软件 编辑:程序博客网 时间:2024/04/27 22:30
全排列
递归方法
思路描述
- 将字符串分为两组,第一组为第一个字符,第二组为剩余的N-1个字符:
- 确定可以放在第一个位置的字符,即:将第一个字符与之后N-1个字符进行交换得到
- 对之后的N-1个字符做全排列
算法实现
void permutation(char *str, char *pBegin) {if (*pBegin == '\0') {cout << str << endl;}for (char *pos = pBegin; *pos != '\0'; pos++) {char tmp = *pos;*pos = *pBegin;*pBegin = tmp;permutation(str, pBegin+1);tmp = *pos;*pos = *pBegin;*pBegin = tmp;}}
字典序法(迭代)
思路描述
- 在当前序列中,从尾端向前寻找两个相邻元素,前一个记为*i,后一个记为*t,并且满足*i < *t。然后再从尾端寻找另一个元素*j,如果满足*i < *j,即将第i个元素和第j个元素对调,并将t个元素之后的所有元素颠倒排序,即就出下一个序列了。
- 如果到最后一个排列next_permutation会返回false,但使用了这个方法后,序列会变成字典序列的第一个,如cba变成abc。就可以继续next了,可以参考next_permutation用法。
算法实现
#include <iostream>#include <algorithm>using namespace std;typedef string::iterator StringItr;void itr_swap(StringItr i, StringItr j){ char tmp = *i; *i = *j; *j = tmp;}void reverse(StringItr i, StringItr j) { while (i < j) { itr_swap(i, j); ++i, --j; } }bool next(string& str) { StringItr start = str.begin(); StringItr end = str.end() - 1; if(start == end) { return false; } StringItr i = start; ++i; if (i == end) return false; i = end; while(true) { StringItr t = i; --i; if (*i < *t) { StringItr j = end; while(!(*i < *j)) j--; itr_swap(i, j); reverse(t, end); return true; } if (i == start) { //all reverse, generate min dictionary reverse(start, end); return false; } }}void permutation(string& str){ if (str.empty()) return; StringItr start = str.begin(); StringItr end = str.end(); sort(start, end); do{ cout << ">>" << str << endl; }while(next(str));}int main(int argc, char *argv[]){ if (argc == 2) { string str(argv[1]); permutation(str); } else { string str = "bac"; permutation(str); }}
组合
递归方法
思路描述
- 对每一个字符而言,可以选择将其加入组合中,也可以选择不将其加入组合中:
- 若选择加入组合,则从后N-1个字符中,选择m-1个字符加入到组合中
- 若不选择加入组合,则从后N-1个字符中,选择m个字符加入到组合中
算法实现
#include <iostream>using namespace std;typedef string::iterator StringItr;void _combination(string& str, StringItr current, int m, char *b, int index){ if (current == str.end()) return; //don't choose current pos _combination(str, current+1, m, b, index); //choose current pos b[++index] = *current; _combination(str, current+1, m, b, index); if (index == (m-1)) { b[m] = '\0'; cout << b << endl; } }void combination(string& str) { char b[str.size() + 1]; for (int i = 1; i < str.size(); i++ ) { _combination(str, str.begin(), i, b, -1); } }int main(int argc, char *argv[]){ if (argc == 2) { string str(argv[1]); combination(str); } else { string str = "abc"; combination(str); } return 0;}
迭代方法-01法
思路描述
- 展开一个数组,其下标表示1~N个数,数组元素的值为1表示其代表的数被选中,为0表示没被选中。
- 初始化:将数组前M个元素置1,表示第一个组合为前M个数
- 然后从左到右扫描数组元素值为“10”组合,找到第一个“10”组合后将其变为01组合,同时将左边所有的“1”全部移动到数组的最左端。
- 当第一个1移动到数组的n-m的位置时,M个1全部移动到最右端,就得到了最后一个组合
算法实现
#include <iostream>using namespace std;void print_result(string& str, int *loc){ int length = str.size(); for (int i = 0; i < length; i++) { if (loc[i]) cout << str[i]; } cout << endl;}int first_1_pos(int *loc, int length){ for (int i = 0; i < length; i++) { if(loc[i]) { return i; } } return -1; }int first_10_pos(int *loc, int length){ for (int i = 0; i < length - 1; i++) { if(loc[i] && loc[i+1] == 0) { return i; } } return -1;}void swap(int &a, int &b){ a = b + a; b = a - b; a = a - b;}void move_1_to_left(int *loc, int end){ for (int old = 0, pos = 0; old < end; old++) { if (loc[old] && pos != old) { loc[pos++] = 1; loc[old] = 0; } }}void _combination(string& str, int *loc, int m){ //initialize loc array int length = str.size(); for (int i = 0; i < length; i++) { if (i < m) loc[i] = 1; else loc[i] = 0; } print_result(str, loc); int first_1 = first_1_pos(loc, length); int end_condition = length - m; //loop to search all m combinations while (first_1 != end_condition) { int first_10 = first_10_pos(loc, length); swap(loc[first_10], loc[first_10+1]); move_1_to_left(loc, first_10); print_result(str, loc); first_1 = first_1_pos(loc, length); }}void combination(string& str){ int length = str.size(); int loc[length]; for (int i = 1; i < length; i++) { _combination(str, loc, i); }}int main(int argc, char *argv[]){ if (argc == 2) { string str(argv[1]); combination(str); } else { string str = "abc"; combination(str); } return 0;}
0 0
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 排列组合算法
- 内存操作算法
- 阿斯顿发生的发生的发生的
- 这又是的哦发送到发送到
- TopCoder入门教程
- 树莓派学习笔记——Model B Model B+ Compute Module Dev Kit的区别和联系
- 排列组合算法
- 上海珍博文物经营有限公司商务网站大全
- WebGL 支持情况检测与已支持浏览器版本汇总
- 这又是的哦发送到发送到
- discuz x2.5插件开发之直接访问插件页面(做简单接口插件)
- 人工智能休眠机制
- java面向对象值继承-子父类中变量的特点
- 这又是的哦发送到发送到
- 食欲大增的鬼打鬼