Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 二进制码的约束计数集_Java_Algorithm_Binary - Fatal编程技术网

Java 二进制码的约束计数集

Java 二进制码的约束计数集,java,algorithm,binary,Java,Algorithm,Binary,问题公式:给定一个长度为l的二进制代码,对于每个t位集(l%t=0),如果至少存在一个值为1的位,我们在结果中加1 我的问题是:如何有效地获得最终结果 例如,我们有一个二进制代码010 110 000,t=3。那么最终结果是2。因为对于000,没有值1的位。对于110,至少存在一个值为1的位。我们在结果上加1。对于010,还存在一个值为1的位。我们在结果上加1。因此,最终结果是2 我的问题是,如何在不扫描每个t位的情况下有效地解决这个问题,这会导致时间复杂度与二进制代码的长度成线性关系 对于计数

问题公式:给定一个长度为l的二进制代码,对于每个t位集(l%t=0),如果至少存在一个值为1的位,我们在结果中加1

我的问题是:如何有效地获得最终结果

例如,我们有一个二进制代码
010 110 000
,t=3。那么最终结果是2。因为对于
000
,没有值1的位。对于110,至少存在一个值为1的位。我们在结果上加1。对于010,还存在一个值为1的位。我们在结果上加1。因此,最终结果是2

我的问题是,如何在不扫描每个t位的情况下有效地解决这个问题,这会导致时间复杂度与二进制代码的长度成线性关系

对于计数集问题(计算一个二进制代码中有多少个1),有一些算法需要固定的时间来解决它,只需执行有限数量的掩码和移位操作,如算法

然而,传统计数集问题的现有算法不能用来解决我的问题

有人知道解决我问题的方法吗?如果使问题更容易解决,则可以假定输入二进制代码的最大长度。

来源:


然后,您可以假设输入是这个问题的64位整数的二进制代码

这里有两种不同的方法

第一次在O(I/t)中运行,通过测试每个集合的所有0位来工作

public static int countSets(int setSize, long bits) {
    Long mask = (1L << setSize) - 1;
    int count = 0;
    for (long b = bits; b != 0; b >>>= setSize)
        if ((b & mask) != 0)
            count++;
    return count;
}

第二种方法首先将位合并到集合的最右边位,例如,使用
input=010 110 000
t=3
,您可以得到:

位=010 110 000
位>>1=001 011 000
位>>2=000 101 100
b(或d)=011111100
然后,它构建一个仅用于检查最右边位的掩码,然后应用掩码并对设置的位进行计数:

mask=001
b&mask=001 000
结果:2

输入的形式是什么?一根绳子?字节数组?输入的形式并不重要。输入只是一个随机的二进制代码。形式非常重要。
String
的解决方案与
byte[]
int
long
BigInteger
值的解决方案没有任何共同之处。然后,您可以假设该问题的输入是64位整数的二进制代码。非常好的“希腊”二进制!谢谢你的答复。昨天我自己想出了一个解决办法,和你的第二个差不多。唯一的区别是时间复杂性分析。在我看来,如果机器是64位或更大的系统,它应该是O(t),这意味着任何按位操作都需要恒定的时间。对于第一个“For”循环,它需要O(t)时间。对于第二个“For”循环,我们可以通过简单地将掩码指定为八进制0111来避免此循环。在应用等式“b&mask”之后,我们可以使用现有的方法,如MIT HAKMEM来计算位集,这需要恒定的时间。因此,总的复杂度应该是O(t)。如果我错了,请纠正我。@Erichang您不能将掩码指定为八进制0111。第二个版本要求掩码为
…10001
,1位之间的距离由
t
确定你谈论麻省理工学院哈克姆数数。你认为
Long.bitCount()
有什么作用?参见javadoc of:“比特旋转”方法(如
highestOneBit
numberOfTrailingZeros
)的实现基于小亨利·S·沃伦的《黑客的喜悦》(Addison Wesley,2002)中的材料。
public static int countSets(int setSize, int bitCount, long bits) {
    long b = bits, mask = 1;
    for (int i = 1; i < setSize; i++)
        b |= bits >>> i;
    for (int i = setSize; i < bitCount; i <<= 1)
        mask |= mask << i;
    return Long.bitCount(b & mask);
}