Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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
Algorithm 恢复数组的元素,给定索引处与位掩码匹配的项的总和_Algorithm - Fatal编程技术网

Algorithm 恢复数组的元素,给定索引处与位掩码匹配的项的总和

Algorithm 恢复数组的元素,给定索引处与位掩码匹配的项的总和,algorithm,Algorithm,假设有一个由2^n元素组成的数组E。例如: E = [2, 3, 5, 7, 11, 13, 17, 19] 不幸的是,有人来扰乱了阵列。他们获取了所有二进制索引形式为1XX的元素,并将它们添加到索引0XX的元素中(即,他们将e[0]+=e[1],e[2]+=e[3]等添加到0XX,并将XX1添加到XX0 更具体地说,他们在数组上运行了以下伪代码: def scramble(e): n = lg_2(len(e)) for p in range(n): m =

假设有一个由
2^n
元素组成的数组
E
。例如:

E = [2, 3, 5, 7, 11, 13, 17, 19]
不幸的是,有人来扰乱了阵列。他们获取了所有二进制索引形式为
1XX
的元素,并将它们添加到索引
0XX
的元素中(即,他们将
e[0]+=e[1]
e[2]+=e[3]
等添加到
0XX
,并将
XX1
添加到
XX0

更具体地说,他们在数组上运行了以下伪代码:

def scramble(e):
    n = lg_2(len(e))
    for p in range(n):
        m = 1 << p
        for i in range(len(e)):
            if (i & m) != 0:
                e[i - m] += e[i]
在对数组进行置乱后(即,您的输入是
e_3
),您将获得该数组。您的目标是恢复
e
的原始第一个元素(即数字2)

恢复2的一种方法是撤消所有的加扰。运行加扰码,但是用
-=
替换
+=/code>。但是,这样做非常昂贵。需要
n2^n
时间。有没有更快的方法

替代形式

换句话说,我给你一个数组
S
,其中索引
I
处的元素是所有元素的总和,索引
j
满足列表
(j&I)==I
。例如,
S[101110]
E[101110]+E[11111 0]+E[101111]+E[111111]
)。给定
S
,恢复
E
元素的成本有多高

111111…
中的项目很简单,因为
S[111111…]=E[111111…]
,但是
S[000000…]
以非统一的方式依赖于
E
中的所有元素,因此似乎很难取回

扩展


如果我们不只是想恢复原始项,而是想恢复与掩码匹配的原始项的总和,该掩码可以指定must-be-1、无约束、must-be-0,该怎么办?这更难吗?

调用数组中的项数
N
,以及正在使用的位掩码的大小
B
so
N=2^B

没有比
O(N)
更好的了

问题中的示例解决方案只是反向运行置乱,需要
O(nb)
时间。我们可以通过丢弃那些不会影响我们在最后读取的实际值的项目,将其减少到
O(N)
。事实上,这使得解读更加简单:只需从数组的前半部分迭代减去后半部分,然后丢弃后半部分,直到剩下一项

def unscrambleFirst(S):
    while len(S) > 1:
        h = len(S)/2
        for i in range(h):
            S = S[:h] - S[h:] #item-by-item subtraction
    return S[0]
速度不可能超过
O(N)
。我们可以用线性代数证明它

  • 原始数组具有
    N
    独立项,即它是一个具有
    N
    自由度的向量
  • 置乱操作仅使用线性操作,因此相当于将该向量乘以矩阵。(矩阵是
    [[1,1],[0,1]]
    B
    次;它最终看起来像a)
  • 置乱操作矩阵是可逆的(这就是为什么我们可以撤消置乱)
  • 因此,加扰向量必须仍然具有
    N
    自由度
  • 但是我们的
    O(N)
    解是加扰向量的每个元素的线性组合
  • 由于加扰向量的元素都必须是线性独立的,才能有
    N
    自由度,我们不能用其他元素的用法重写任何一个元素的用法
  • 因此,我们不能改变我们所依赖的项目,我们知道我们在一种情况下依赖所有项目,所以在所有情况下都必须依赖所有项目

希望这足够清楚。混乱分配第一个项目的方式要求您查看每个项目才能将其取回。

我很难理解您所说的内容。首先,您是指
n=3
,因此
E
具有
2^3=8
元素吗?“他们拿走了所有二进制索引的元素…”让我困惑。你能给出这个加扰程序的(伪)代码吗?你能介绍一下你的
n2^n
解读过程吗?
def unscrambleFirst(S):
    while len(S) > 1:
        h = len(S)/2
        for i in range(h):
            S = S[:h] - S[h:] #item-by-item subtraction
    return S[0]