面试题精选(62):组合算法
来源:互联网 发布:北京国税申报软件 编辑:程序博客网 时间:2024/05/20 03:46
计算一个集合的组合,最直观的方式是使用递归:首先选择一个元素,然后在剩下的集合中选择其余元素。代码实现也很简单,下面的代码计算集合的所有可能的组合(一个或多个元素):
#include <iostream>
#include <vector>
#include <iterator>
#include <cassert>
using namespace std;
template <typename ElemType>
void CalcCombination(const ElemType elements[], int num, int k, vector<ElemType> &pre)
{
assert(k <= num);
if (k == 0) {
// output one combination
copy(pre.begin(), pre.end(), ostream_iterator<ElemType>(cout, " "));
cout << endl;
return;
}
for (int i = 0; i <= num - k; ++i) {
pre.push_back(elements[i]);
CalcCombination(elements + i + 1, num - i - 1, k - 1, pre);
pre.pop_back();
}
}
template <typename ElemType>
void CalcCombination(const ElemType elements[], int num)
{
vector<ElemType> one;
for (int i = 1; i <= num; ++i)
CalcCombination(elements, num, i, one);
}
int main()
{
char elements[] = {'a', 'b', 'c', 'd'};
const int NUM = sizeof(elements) / sizeof(elements[0]);
CalcCombination(elements, NUM);
}
运行结果:
a
b
c
d
a b
a c
a d
b c
b d
c d
a b c
a b d
a c d
b c d
a b c d
另外,还可以使用位运算来实现组合计算。对于元素个数为n的集合,可以使用n位来表示每一个元素,位1表示该元素被选中,位0表示该位未被选中。那么,计算组合C(n, k)就相当于计算出n位数中有k个1位的所有数,每一个计算出的数就表示一个选中的组合。例如,下面的代码可计算最多32个元素的C(n,k)组合(如果需要用此方法计算更多元素的组合,则需要使用更多位数的数来表示组合):
#include <iostream>
#include <cassert>
using namespace std;
typedef unsigned int uint32_t;
// 输出数表示的组合
template <typename T>
void OutputCombination(const T elements[], int num, uint32_t combinationBits)
{
for (int i = 0; i < num; ++i) {
if (combinationBits & uint32_t(1) << i)
cout << elements[i];
}
cout << endl;
}
// 产生跟pre有相同的1位,且比pre大的下一个数,如果不存在,返回0
uint32_t NextCombination(uint32_t pre)
{
uint32_t lastOne = pre & -pre;
uint32_t high = pre + lastOne;
if (high == 0)
return 0; // 已经达到最大值
uint32_t mid = high ^ pre;
uint32_t low = (mid >> 2) / lastOne;
return high | low;
}
template <typename T>
void GenAllCombination(const T elements[], int num, int k)
{
assert(1 <= num && num <= 32 && 1 <= k && k <= num);
// 产生最小的具有k个1的数
uint32_t number = (uint32_t(1) << k) - 1;
// 具有k个1的最大的num位数
uint32_t maxNumber = number << (num - k);
for (; true; number = NextCombination(number)) {
OutputCombination(elements, num, number);
if (number == maxNumber)
break;
}
}
int main()
{
const int NUM = 5;
char elements[NUM];
for (int i = 0; i < NUM; ++i)
elements[i] = 'a' + i;
GenAllCombination(elements, NUM, 2);
}
程序运行结果如下:
ab
ac
bc
ad
bd
cd
ae
be
ce
de
- 面试题精选(62):组合算法
- 面试题精选(64):元素可重复组合算法
- 程序员面试题精选100题-字符串的组合[算法]
- 面试题精选(63):排列算法
- 程序员面试题精选-- 字符串的组合
- 程序员面试题精选-- 字符串的组合
- 组合算法面试题
- 组合算法面试题
- 程序员面试题精选100题(59)-字符串的组合[算法]
- 面试题精选(71):倒水倒油类算法
- 面试题精选(一)
- 面试题精选(二)
- 程序员面试题精选{57):求n的加法组合
- 程序员面试题精选{57):求n的加法组合
- 程序员面试题精选100题(59)-字符串的组合
- 程序员面试题精选100题(59)-字符串的组合
- 程序员面试题精选100题(59)-字符串的组合
- 程序员面试题精选100题(62)-C/C++/C#面试题(5)
- 加密解密
- sprintf 使用小结
- (转贴).NET中Excel数据访问汉字丢失的分析与解决
- Extjs 关于文件上传file 框 可输入问题解决
- 转载:我的读博经历回顾与经验分享
- 面试题精选(62):组合算法
- JavaScript传说中的图片截取(只显示一张图片的某个部分)
- Openfire Connection Manager 配置
- SAP ABAP
- 在应用程序级别之外使用注册为allowDefinition='MachineToApplication' 的节是错误的
- ACCESS的真假:二、检查记录有无再insert 或 update 比 不管有无直接 delete 再 insert 快吗?
- SAP ABAP -----ABAP 有用的日期FUNCTION
- SAP常用知识点{系统变量|TCODE|消息类型|数据类型|变量声明|Internal Table}
- CRM下午茶:寻根Siebel