题目:
9. One problem with trading more space to use less time is that initializing the space can itself take a great deal of time. Show how to circumvent this problem by designing a technique to initialize an entry of a vector to zero the first time it is accessed. Your scheme should use constant time for initialization and for each vector access, and use extra space proportional to the size of the vector.
Because this method reduces initialization time by using even more space, it should be considered only when space is cheap, time is dear and the vector is sparse.
提供的参考答案:
The effect of initializing the vector data[0..n-1] can be accomplished with a signature contained in two additional n-element vectors, from and to, and an integer, top. If the element data[i] has been initialized, then from [i] < top and to[from[i]] = i. Thus from is a simple signature ,and to and top together make sure that from is not accidentally signed by the random contents of memory.
Blank entries of data are uninitialized in this picture:
data : | |3 | |2 | | 8 | | |
from: | |0 | |2 | | 1 | | |
to: |1|5 |3| | | | | |
The variable top is initially zero; the array element i is first accessed by the code
from[i] = top
to[top] = i
data[i] = 0
top++
This problem and solution are form Exercise 2.12 of Aho, Hopcroft and Ullman's Design and Analysis of Computer Algorithms. It combines key indexing and a wily signature scheme. It can be used for matrices as well as vectors.
首先,我们需要明确问题是什么。
在这里,我们有一个稀疏的数组需要访问,并且在第一次访问的时候将其初始化为0. 因为数组很大,并且需要访问的数组元素很稀疏,而程序要求的时间很宝贵。
所以,我们不能直接将data数组的各个元素都初始化为0.
我们需要做的是在第一次数组data中的某个元素的时候,将其初始化为0. 如果之后再次访问到该元素,应该能够判断其是否已经被初始化过,避免多次初始化从而覆盖数据。
在提供的解决方案中,就使用了from,to两个向量和top变量来保存哪些变量已经被初始化了。
当我们访问索引为i的data元素时,我们通过判断form[i]是否小于top,并且to[from[i]]是否等于i来判断元素树否被初始化过。
需要注意的是我们使用to向量的原因是为了防止from中的未经初始化的数据刚好因为小于top而导致出现错误判断。也就是说,我们是不对from和to向量进行初始化的(因为我们连对data进行初始化的成本都不肯),所以无法判断from中的数据哪些是我们写入的,哪些是原来就有的。于是,我们就通过增加一个to数组,并且增加一个判断条件来保证我们的判断是正确的。
当然,这样的保证也并不是绝对正确的。只是小概率事件,直接忽略了吧???
综上:
我们在访问data中索引为i的元素时,通过条件from[i]<top和to[from[i]]=i来判断该数据是否被初始化过。
如果已被初始化过,就直接访问该数据;
否则,使用如下的语句对其进行初始化,并且在from,to和top中保存该数据已被初始化过这个信息:
from[i]=top;
to[top]=i
data[i] = 0
top++.
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kankanli/archive/2009/10/29/4744340.aspx