C++ 创建按位集排序的序列
我正在寻找一个可逆函数C++ 创建按位集排序的序列,c++,math,C++,Math,我正在寻找一个可逆函数unsigned f(unsigned),其中f(I)中设置的位数随I增加,或者至少不减少。显然,f(0)必须是0,并且f(~0)必须排在最后。在两者之间有更多的灵活性。在f(0)之后,对于每个给定的数字k,接下来的32*值必须是1U,我们知道有binom(n,k)n-位整数正好具有k位的值1。现在,我们可以生成一个包含n+1整数的查找表,该表为每个k存储多少个数字少于一位。然后可以使用此查找表查找f(i)的一位的编号o 一旦我们知道了这个数字,我们就从i中减去这个位数的查
unsigned f(unsigned)
,其中f(I)
中设置的位数随I
增加,或者至少不减少。显然,f(0)
必须是0,并且f(~0)必须排在最后。在两者之间有更多的灵活性。在f(0)之后,对于每个给定的数字k
,接下来的32*值必须是1U,我们知道有binom(n,k)
n
-位整数正好具有k
位的值1。现在,我们可以生成一个包含n+1
整数的查找表,该表为每个k
存储多少个数字少于一位。然后可以使用此查找表查找f(i)
的一位的编号o
一旦我们知道了这个数字,我们就从i
中减去这个位数的查找表值,这就为给定位数的数字留下了排列索引p
。虽然我还没有在这方面做过研究,但我很确定存在一种方法,可以找到一个std::vector
的pth置换,该置换在最低位用零和o
一初始化
反向函数
同样,查找表也很方便。我们可以通过计算输入整数中的一位并在查找表中读取,直接计算少于一位的前面数字的数量。然后“只”需要确定置换索引并将其添加到查找的值中,就完成了
免责声明
当然,这只是一个粗略的轮廓,有些部分(特别是涉及排列)可能需要比听起来更长的时间
附加
你说了你自己
我试图用它来标记一个大数据集,并按搜索顺序排列优先级
对我来说,这听起来像是从低汉明距离到高汉明距离。在这种情况下,有一个增量版本就足够了,该版本可以从以前的版本生成下一个数字:
unsigned next(unsigned previous)
{
if(std::next_permutation(previous))
return previous;
else
return (1 << (1 + countOneBits(previous))) - 1;
}
unsigned next(unsigned previous)
{
if(std::next_置换(previous))
返回上一个;
其他的
return(1Ok,似乎我有一个合理的答案。首先,让我们定义binom(n,k)
为我们可以从n
位中设置k
的方法的数量。这是经典的Pascal三角形:
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
...
1 2
1 3 4
1 4 7 8
1 5 11 15 16
1 6 16 26 31 32
1 7 22 42 57 63 64
1 8 29 64 99 120 127 128
1 9 37 93 163 219 247 255 256
...
易于计算和缓存。请注意,每行的总和是1。我认为这些问题的目的是找到二进制数的总顺序,这样每个数字的位数都会减少,而一个位数越多。位数相同的数字可以具有任意但确定的顺序。不同的事物的真正目的是什么只有几位的de>?例如,像汉明距离?这个可能很方便。@hasan:“设置的位数”。在英语中,你可以经常省略这样一对词:“走在那里的人…”->“走在那里的人…”你确定不能增量生成序列吗?那相当容易。在那些binom(n,k)
置换中,binom(n-1,k)
第一位为零,而binom(n-1,k-1)
设置第一个位。听起来我需要走帕斯卡三角形。听起来我需要走帕斯卡三角形。
什么时候?要得到排列?@MSalters:关于子集的大小,第一个位是0/1:这些计算只适用于k=1..n-1
但其他两种情况(k=0/n)当然是琐碎的,所以这是有效可逆的。
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
...
1 2
1 3 4
1 4 7 8
1 5 11 15 16
1 6 16 26 31 32
1 7 22 42 57 63 64
1 8 29 64 99 120 127 128
1 9 37 93 163 219 247 255 256
...