根据设置的位数计算组合
Computing Combinations on basis of number of bits set
我需要计算在 0<=r<=n 的时候选择 r 的 n 个事物的所有可能组合,一种方法是生成最多 0 到 2^n-1 的数字。但是我需要生成这些数字,以便根据该数字中设置的位数对数字进行排序。对于 n=3:
0 // numbers with 0 bits set
1 2 4 // numbers with 1 bits set
3 5 6 // numbers with 2 bits set
7 // numbers with 3 bits set
我需要知道如何生成数字,以便它们按位集的递增/递减顺序排序?
实现常规算法来生成组合,但也保留一个额外的数组,您可以在其中存储编码为 1 位集的数字。然后,对于生成的每个组合,将数字替换为位于相应位置的数字减去我描述的数组中的 1。
这里很好地
介绍了一些项目的所有组合quant_dev。
这是一个简单的方法函数,用于计算数字表示中设置的位数:
// Counts how many bits are set in the representation of the input number n
int numOfBitsSet(int n)
{
int cnt = 0;
while (n != 0)
{
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
以下是如何在 (C++11) 程序中使用它,该程序可以执行您想要的操作:
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
// For instance...
int n = 3;
// Fill up a vector of 2^n entries (0 .. 2^(n - 1))
vector<int> v(1 << n);
iota(begin(v), end(v), 0);
// For each number of bits...
for (size_t i = 0; i <= n; i++)
{
cout << "Numbers with " << i << " bits set: ";
// Find the first number with i bits set...
auto it = find_if(begin(v), end(v), [i] (int x) {
return (numOfBitsSet(x) == i);
});
while (it != end(v))
{
cout << *it << " ";
// Find the next number with i bits set...
it = find_if(next(it), end(v), [i] (int x) {
return (numOfBitsSet(x) == i);
});
}
cout << endl;
}
}
如果 C++11 不适合您,则必须使用函子而不是 lambda,并将std::iota
替换为手动循环:
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
struct bit_count_filter
{
bit_count_filter(int i) : _i(i) { }
bool operator () (int x) const { return numOfBitsSet(x) == _i; }
int _i;
};
int main()
{
// For instance...
int n = 3;
// Fill up a vector of 2^n entries (0 .. 2^(n - 1))
vector<int> v(1 << n);
for (size_t i = 0; i < v.size(); i++)
{
v[i] = i;
}
// For each number of bits...
for (size_t i = 0; i <= n; i++)
{
cout << "Numbers with " << i << " bits set: ";
// Find the first number with i bits set...
auto it = find_if(begin(v), end(v), bit_count_filter(i));
while (it != end(v))
{
cout << *it << " ";
// Find the next number with i bits set...
it = find_if(next(it), end(v), bit_count_filter(i));
}
cout << endl;
}
}
你可以递归地做到这一点:
void setnbits(unsigned int cur, int n, int toset, int max)
{
if(toset == 0)
{
printf("%d ", cur >> (n + 32 - max) , n);
return;
}
toset--;
for(int i = 1 ; i <= n-toset ; i++)
{
setnbits((cur >> i) | 0x80000000, n-i, toset , max);
}
}
可以这样称呼:
for(int z = 0 ; z < 4 ; z++)
{
printf("%d bits: ", z);
setnbits(0, 3, z, 3);
printf("n");
}
指纹:
0 bits: 0
1 bits: 1 2 4
2 bits: 3 5 6
3 bits: 7
不保证数字按数字顺序排列。
这很容易。有两种情况:
1) 最后 1 位之前有 0 位: 000111001001 -> 000111001010.
您应该将其向左移动
2)有一个1位链: 0001101111 00-> 000111000111
然后,您应该将最后 1 位移动到左侧最接近的 0 位(链之前),并将该链的所有其他位向右移动。
您将以这种方式按递增顺序获得所有需要的数字。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 计算数组重复次数的组合的有效算法,加起来达到给定的总和
- 犰狳C++:带有模量计算的线性组合
- 为什么组合的上限和下限比较的计算结果总是为 true?
- 如何计算数组整数的总可能组合
- 向量的高效组合最小值和平均值计算
- 如何计算特定的卡组合索引
- 计算句子的校验和(XOR)(由不同变量/类型的组合形成)
- 在C++中实现和包装函数组合以进行惰性计算
- 我如何计算硬币变化中的不同组合
- 在 C++11 中计算字母和单词的双字母组合的 std::线程向量的问题
- 使用在组合类中计算的数据构造成员类
- 如何计算前缀和后缀运算符的组合
- 计算N个整数组合的绝对值
- 如何有效地计算给定数字的所有不同组合的按位异或值之和
- 根据设置的位数计算组合