实现非常有效的位结构

时间:2018-10-17 17:27:21

标签: java algorithm data-structures complexity-theory pseudocode

我正在寻找以pesudo代码或Java或js解决以下问题的解决方案:

我们需要实现一种有效的位结构来保存N位数据(您也可以将这些位视为布尔值,on / off)。

我们需要支持以下方法: 初始化(n) 获取(索引) 设置(索引,正确/错误) setAll(True / false)

现在我得到了一个全部带有o(1)的解决方案,除了init是o(n)之外。想法是创建一个数组,每个索引在其中保存一点值。为了支持setAll,我还将保存带位蒸气的时间戳,以了解是从tge数组还是从tge的最后一个setAll值获取值。初始化中的o(n)是因为我们需要遍历该数组以使其无效,否则它将产生垃圾,这可能是任何事情。现在,我被要求找到一个初始化也为o(1)的解决方案(我们可以创建一个数组,但是我们无法清除垃圾,垃圾甚至看起来像是有效数据,这是错误的并使解决方案变糟,我们需要有效的解决方案)。

更新: 这是一种算法要求,而不是特定于语言的要求。我在面试问题中遇到了它。由于内存限制,使用整数表示位数组还不够好。我被告知,它与数组中的垃圾数据的某种智能处理有关,而无需在初始化中进行任何处理,使用某种机制可以避免这种情况,因为如果数组中的垃圾数据(但我不是确定如何)。

2 个答案:

答案 0 :(得分:1)

使基于哈希图的 lazy 数据结构(虽然哈希图有时可能比o(1)的访问时间更短)具有32位值(8、16、64整数也很合适) )用于存储和辅助字段InitFlag

要清除所有内容,请使用InitFlag = 0制作一个空白地图(删除旧地图是GC在Java中的工作,对吗?)

要全部设置,请用InitFlag = 1制作空白地图

在更改某些位时,请检查是否存在相应的int密钥bitnum/32。如果是,则只需更改bitnum&32位,如果没有,且位值与InitFlag不同-使用基于InitFlag(全为零或全为1)的值创建密钥,并更改所需的位。

检索某位时,请检查是否存在对应的密钥。如果是,则提取位;否则,获取位InitFlag

SetAll(0):   ifl = 0, map - {}
SetBit(35):   ifl = 0, map - {1 : 0x10}
SetBit(32):   ifl = 0, map - {1 : 0x12}
ClearBit(32):   ifl = 0, map - {1 : 0x10}
ClearBit(1):   do nothing, ifl = 0, map - {1 : 0x10}
GetBit(1):     key=0 doesn't exist,  return ifl=0
GetBit(35):     key=1 exists,  return map[1]>>3 =1
SetAll(1):      ifl = 1, map = {}
SetBit(35):     do nothing
ClearBit(35):   ifl = 1, map - {1 : 0xFFFFFFF7 = 0b...11110111}
and so on

答案 1 :(得分:0)

如果这是大学/高中计算机科学考试或作业分配问题-我怀疑他们试图让您使用 BOOLEAN BIT-WISE LOGIC -具体来说,请在一个int或long。我怀疑(但是我不是读书者-我可能错了!)使用“数组”确实是 完全 ,您的老师希望您避免这样做。

例如-此报价是从Google的搜索结果中复制的:

  

long long数据类型 64位二进制补码整数 。的   带符号的long的最小值为-263,最大值为263-1。   在Java SE 8和更高版本中,您可以使用long数据类型表示一个   无符号64位长,最小值为0,最大值为   值264-1

这意味着Java中的单个long变量可以存储64个按位值:

long storage;
// To get the first bit-value, use logical-or ('|') and get the bit.
boolean result1 = (boolean) storage | 0b00000001; // Gets the first bit in 'storage'
boolean result2 = (boolean) storage | 0b00000010; // Gets the second
boolean result3 = (boolean) storage | 0b00000100; // Gets the third
...
boolean result8 = (boolean) storage | 0b10000000; // Gets the eighth result.

我可以为您编写全部内容,但是我不能100%确定您的实际规格-如果使用很长的内容,则只能存储64个单独的二进制值。如果您想要任意数量的值,则必须使用所需的“ long”数。

以下是有关二进制/布尔值的SO帖子: Binary representation in Java

以下是有关位移的SO帖子: Java - Circular shift using bitwise operations

同样,这将是一项工作,而我不会写整个项目。但是,get(int index)set(int index, boolean val)方法将涉及数字1的按位移位。

int pos = 1;
pos = pos << 5;  // This would function as a 'pointer' to the fifth element of the binary number list.
storage | pos;  // This retrieves the value stored as position 5.