布尔数组前缀的串联

时间:2018-07-18 10:24:47

标签: bit-manipulation

我有一个大小为 n 的布尔数组A,我想通过以下方式进行转换:连接大小为1,2,.. n 的每个前缀。

例如,对于 n = 5,它将把“ abcde”转换为“ aababcabcdabcde”。

当然,一种简单的方法可以遍历每个前缀并使用基本位操作(移位,掩码和加号);因此这种方法的复杂性显然是O( n )。

关于here之类的位操作,有一些众所周知的技巧。

我的问题是:是否可以通过使用位操作来实现一种比O( n )更好的复杂度的,用于上述转换的更快算法?

我知道这种改进的兴趣可能只是理论上的,因为简单的方法在实践中可能是最快的,但是我仍然对是否存在理论上的改进感到好奇。

为精确起见,我需要执行此转换 p 次,其中 p 可能比 n 大;可以对给定的 n 进行一些预计算,然后再用于计算 p 转换。

2 个答案:

答案 0 :(得分:0)

我不确定这是否是您要寻找的东西,但是这里有一个不同的算法,根据您的假设可能会很有趣。

首先计算两个仅取决于n的掩码,因此对于任何特定的n这些都是常量:

  • C(复制掩码),这是设置了第n位且长度为n²位的掩码。因此对于n = 5C = 0000100001000010000100001。这将用于创建串联在一起的n个A副本。
  • E(提取掩码),这是一个掩码,指示要从大串联中获取哪些位,该掩码由n乘以n位的n位块构成,值分别为1、3、7、15。例如n = 5E = 1111101111001110001100001。如有必要,请在左侧填充零。

然后采用A并构造前缀串联的实际计算是:

pext(A * C, E)

pextcompress_right的地方,丢弃提取掩码为0的位,并将其余位压缩到右侧。

可以用类似“加倍”的技术来代替乘法:(也可以用来计算C掩码)

l = n
while l < n²:
    A = A | (A << l)
    l = l * 2

通常会产生太多的A的串联副本,但是您可以通过不看它而假装不存在多余的内容(pext会丢弃任何多余的输入)。有效地为未知且任意大的E生成n似乎比较困难,但这实际上不是这种方法的用例。

实际时间复杂度取决于您的假设,但是当然在完整的“任意位数”设置中,乘法和压缩都是重量级操作,而输出的大小为输入大小的平方的事实确实无济于事。如果n足够小,例如n²<= 64(取决于字长),那么一切都适合一个机器字,那么一切都很好(即使对于未知的n,因为所有必需的掩码都可以预先计算)。另一方面,对于如此小的n,也可以将整个对象表化,以查找对(n,A)。

答案 1 :(得分:0)

我可能已经找到另一种进行方式。

这个想法是使用乘法将初始输入I传播到正确的位置。乘法系数J是对于[1:n]中的i,在位置i *(i-1)/ 2处将其比特设置为1的向量。

但是,I与J的直接相乘将提供许多不需要的项,因此该想法是

  1. 屏蔽向量I和J的某些位
  2. 将这些被屏蔽的向量相乘
  3. 从结果中删除一些垃圾。

因此,我们需要进行多次迭代;最终结果是中间结果的总和。我们可以将结果写为“((I&Ai)* Bi)&Ci的i上的总和”,因此每次迭代有2个掩码和1个乘法(Ai,Bi和Ci是取决于n的常数)。

该算法似乎是O(log(n)),所以它比O(log(n)^ 2)更好,但是它需要乘法运算,这可能会很昂贵。还要注意,该算法需要大小为n *(n + 1)/ 2的寄存器,该寄存器要好于n ^ 2。

以下是n = 7的示例

Input:
  I = abcdefg

We set J = 1101001000100001000001

We also note temporary results:
  Xi = I & Ai
  Yi = Xi * Bi
  Zi = Yi & Ci

iteration 1
----------------------------
1                              A1
11 1  1   1    1     1         B1
11 1  1   1    1     1         C1
----------------------------
a                              X1
aa a  a   a    a     a         Y1   
aa a  a   a    a     a         Z1


iteration 2
----------------------------
 11                            A2
 1 1  1   1    1     1         B2
  1 11 11  11   11    11       C2
----------------------------
 bc                            X2
  bcbc bc  bc   bc    bc       Y2
  b bc bc  bc   bc    bc       Z2


iteration 3
----------------------------
   1111                        A3
      1   1    1     1         B3
         1   11   111   1111   C3
----------------------------
   defg                        X3
         defgdefg defg  defg   Y3
         d   de   def   defg   Z3


FINAL SUM
----------------------------
aa a  a   a    a     a         Z1
  b bc bc  bc   bc    bc       Z2
         d   de   def   defg   Z3
----------------------------
aababcabcdabcdeabcdefabcdefg   SUM