我有一个大小为 n 的布尔数组A,我想通过以下方式进行转换:连接大小为1,2,.. n 的每个前缀。
例如,对于 n = 5,它将把“ abcde”转换为“ aababcabcdabcde”。
当然,一种简单的方法可以遍历每个前缀并使用基本位操作(移位,掩码和加号);因此这种方法的复杂性显然是O( n )。
关于here之类的位操作,有一些众所周知的技巧。
我的问题是:是否可以通过使用位操作来实现一种比O( n )更好的复杂度的,用于上述转换的更快算法?
我知道这种改进的兴趣可能只是理论上的,因为简单的方法在实践中可能是最快的,但是我仍然对是否存在理论上的改进感到好奇。
为精确起见,我需要执行此转换 p 次,其中 p 可能比 n 大;可以对给定的 n 进行一些预计算,然后再用于计算 p 转换。
答案 0 :(得分:0)
我不确定这是否是您要寻找的东西,但是这里有一个不同的算法,根据您的假设可能会很有趣。
首先计算两个仅取决于n
的掩码,因此对于任何特定的n
这些都是常量:
C
(复制掩码),这是设置了第n位且长度为n²位的掩码。因此对于n = 5
,C = 0000100001000010000100001
。这将用于创建串联在一起的n个A副本。E
(提取掩码),这是一个掩码,指示要从大串联中获取哪些位,该掩码由n乘以n位的n位块构成,值分别为1、3、7、15。例如n = 5
,E = 1111101111001110001100001
。如有必要,请在左侧填充零。然后采用A并构造前缀串联的实际计算是:
pext(A * C, E)
在pext
为compress_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的直接相乘将提供许多不需要的项,因此该想法是
因此,我们需要进行多次迭代;最终结果是中间结果的总和。我们可以将结果写为“((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