【问题标题】:Is constant time cascade-computing possible?恒定时间级联计算是否可行?
【发布时间】:2017-10-08 06:47:03
【问题描述】:

这是一个关于计算机技术限制的教育目的问题。
我有一种心态,下面的程序是不可能创建的。

假设我必须开发一个累积统计数据结构。
这是规范:-

  • 用户可以在O(1)update(i,value)data[i](平均情况)。
  • 用户可以在O(1)中查询getAccu(i) = data[0]+data[1]+...+data[i](平均情况)。
  • 我不能以任何方式假定调用这两个函数的顺序。

这是我的代码 (coliru demo)。
但它不符合上述要求:-

#include <iostream>
#include <vector>
int data[5]={0,1,2,3,4};
int accu[5]={0,1,3,6,10};
/** assume that index always >=1 */
void update(int index,int value){  //O(n) i.e. O(array length)
    data[index]=value;
    for(int n=index-1;n<5;n++){
        accu[n]=accu[n-1]+data[n];
    }
}
int getAccu(int index){            //O(1)
    return accu[index];
}
int main(){
    update(2,12);
    //note: data = 0,1,12,3,4
    //      accu = 0,1,13,16,20
    std::cout<<getAccu(3)<<std::endl; //16
    //update() ... getAccu()... update() ...
}

不受内存存储大小和数据结构类型的限制,
是否可以将update(index,value)getAccu(index) 都设为O(1)

如果是,如何?如果不是,为什么?

抱歉这个晦涩的话题。我找不到更合适的了。

【问题讨论】:

  • 这与计算技术的限制无关。它与对多个连通变量的恒定时间更新的任意要求的限制有关。
  • @Peter 我想这可能是可能的,但我们目前的研究还没有达到这一点。前任。在哈希发明之前的过去,几乎在每个操作中都无法找到具有 O(1) 的通用数据结构。 ....我认为这是其中之一。 ....如果您仍然认为我使用了不正确的词,请随时编辑它。谢谢。 :)
  • 使用某种树,您可以对这两个操作执行log n。然后,使更新变得懒惰,您可以检测到 2 个查询之间有很多更新的情况并以不同的方式处理它。一切恒定的时间似乎都是乐观的。
  • @Marc Glisse 听起来不错....这对我来说太难了....您能详细说明一下吗?我很兴奋。
  • @cppBeginner 对于 log n,其想法是维护一个平衡的二叉搜索树,它另外在每个节点中存储以该节点为根的子树的总数。更新一个值时,只需更新从根到该元素的路径中的 log n 小计。计算累加器只是从根中找到正确的节点,每次向右时加上左边的小计。

标签: c++ arrays performance data-structures


【解决方案1】:

在恒定时间内做所有事情似乎很乐观。如果您不介意O(log n) 的复杂性,您可以维护一个平衡的二叉树,在每个节点中存储以该节点为根的子树的总数。

当您更新一个值时,您只需要更新从根到该元素的路径中的 log n 小计。

计算累加器只是从根开始定位右节点,每次向右时加上左小计。

您可以不急于进行更新,而是将它们添加到待更新项目列表中,然后当您收到查询并且该列表不为空时,您可以在log n 中进行每次更新或者如果有很多更新,只更新 O(1) 中的值并重新计算 O(n) 中的整个累加器,但只有在 2 个查询之间可能会得到很多更新时,这才值得。

【讨论】:

  • 这是一个很好的答案,谢谢。你是从哪里得到这个想法的?即这种很酷的技术有名字吗?我想了解更多。
  • 不知道,在树中存储小计是一种相当标准的技术,但我没有具体的例子。
猜你喜欢
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 2022-06-13
  • 1970-01-01
  • 2013-06-17
  • 2015-12-31
  • 2016-04-24
相关资源
最近更新 更多