设计一个数据结构来保存大量数据

时间:2013-08-09 17:55:01

标签: data-structures

我在接受采访时被问到以下问题,我无法解决任何指示,这将非常有帮助。

我有100个文件,每个大小10 MB,每个文件的内容都是一些String映射到一个整数值。

string_key =整数值

 a=5
 ba=7
 cab=10 etc.. 

可用的物理RAM空间为25 MB。如何设计数据结构:

For any duplicate string_key, the integer values can be added
Display the string_key=integer value sorted in a alphabetical format

约束:

All the entries of a file could be unique. All of the 10*1000MB of data could be unique string_key mapping to an integer value. 

解决方案1:

我正在考虑一个接一个地加载每个文件并将信息存储在一个hashmap中,但是这个hashmap会非常庞大​​,如果所有文件都包含唯一数据,则RAM中没有足够的可用内存。

还有其他想法吗?

使用noSqldb不是一种选择。

1 个答案:

答案 0 :(得分:2)

这是我对它的刺痛。基本上,我们的想法是使用一系列小型二进制树来保存已排序的数据,动态创建并将它们保存到磁盘以节省内存,并使用链接列表对树本身进行排序。

手动版:

根据条目的键,按字母顺序创建二叉树。每个条目都有一个键和一个值。每棵树作为属性具有其第一个和最后一个键的名称。我们分别加载每个文件,并逐行在树中插入一个条目,自动对其进行排序。当树的内容大小达到10 mb时,我们将树分成两棵5 mb的树。我们将这两棵树保存到磁盘上。为了跟踪我们的树木,我们保留了一系列树木及其名称/位置以及它们的第一个和最后一个属性的名称。从现在开始,对于fileN中的每一行,我们使用列表来找到要插入的适当树,将该树加载到内存中,并执行必要的操作。我们继续这个过程,直到我们结束。

使用此方法,加载到内存中的最大数据量不会超过25 MB。总是有一个正在加载的文件N(10mb),一个加载的树(最多10mb),以及一个树的数组/列表(希望不会超过5mb)。

稍微严格的算法:

  1. 初始化一个排序的二叉树B,其条目为(key, value)元组,根据条目的属性key排序,并具有属性name, size, first_key, last_key其中{{1是一些任意唯一的字符串,name是以字节为单位的大小。

  2. 初始化一个已排序的链接列表size,其条目是L形式的元组,对条目属性(tree_name, first_key)进行了排序。这是我们的树木清单。将元组first_key添加到(B.name, B.first_key)

  3. 假设文件名为L,我们继续使用伪代码编写的以下算法,该算法恰好类似于python。 (我希望我在这里使用的未声明的函数是自解释的)

    file1, file2, ..., file100
  4. 然后我们只是迭代列表并打印出每个相关的树:

    for i in [1..100]:
        f = open("file" + i)   # 10 mb into memory
        for line in file:
            (key, value) = separate_line(line)
    
            if key < B.first_key or key > B.last_key:
                B = find_correct_tree(L, key)
    
            if key.size + value.size + B.size > 10MB:
                (A, B) = B.split()     # supp A is assigned a random name and B keeps its name
                L.add(A.name, A.first_key)
                if key < B.first_key:
                    save_to_disk(B)
                    B = A      # 5 mb out of memory
                else:
                    save_to_disk(A)
    
            B.add(key)
    save_to_disk(B)
    

    这有点不完整,例如为了完成这项工作,您每次 for (tree_name, _) in L: load_from_disk(tree_name).print_in_order() 更改时都必须不断更新列表L;而且我没有严格证明这在数学上使用了25 mb。但我的直觉告诉我,这可能会奏效。还有更有效的方法来排序树,而不是保留一个排序的链表(哈希表可能?)。