【发布时间】: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