Data structures 设计数据结构以保存大量数据

Data structures 设计数据结构以保存大量数据,data-structures,Data Structures,在一次采访中,我被问到了以下问题,我无法解决任何关于这方面的问题,这将非常有帮助 我有100个文件,每个文件大小为10MB,每个文件的内容都是一些字符串映射到一个整数值 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

在一次采访中,我被问到了以下问题,我无法解决任何关于这方面的问题,这将非常有帮助

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

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不是一个选项

这是我的尝试。基本上,这个想法是使用一系列小的二叉树来保存已排序的数据,动态创建并保存到磁盘以节省内存,并使用链表对树本身进行排序

手摇版:

创建一个二叉树,根据其条目的键按字母顺序排序。每个条目都有一个键和一个值。每个树都有其第一个键和最后一个键的名称作为属性。我们分别加载每个文件,并逐行在树中插入一个条目,这将自动对其进行排序。当树的内容大小达到10MB时,我们将树拆分为两棵各为5MB的树。我们将这两棵树保存到磁盘中。为了跟踪我们的树,我们保存了一个树数组及其名称/位置以及第一个和最后一个属性的名称。从现在起,对于文件中的每一行,我们使用列表找到要插入的相应树,将该树加载到内存中,并执行必要的操作。我们将继续这一进程,直到我们到达终点

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

更严格的算法:

  • 初始化已排序的二叉树
    B
    ,其条目是
    (键,值)
    元组,根据条目的属性
    key
    排序,并具有属性
    名称、大小、第一个键、最后一个键
    ,其中
    名称
    是一些任意唯一的字符串,
    大小
    是以字节为单位的大小

  • 初始化已排序的链表
    L
    ,其条目是
    (树名,首键)
    按条目属性
    首键
    排序的基本元组。这是我们的树木名单。将元组
    (B.name,B.first_键)
    添加到
    L

  • 假设文件名为
    file1,file2,…,file100
    ,我们继续执行以下算法,该算法是用一个与python非常相似的伪代码编写的。(我希望我在这里使用的未声明函数是不言自明的)


    这有点不完整,例如,要实现这一点,您必须在每次
    first\u键更改时不断更新列表
    L
    ;我还没有严格证明这在数学上使用了25MB。但我的直觉告诉我,这可能会奏效。与保存已排序的链表(可能是哈希表?)相比,可能还有更有效的方法对树进行排序。

    我不知道这是否是他们正在寻找的答案,但1)对100个文件中的每个文件进行排序,一次一个。将排序后的输出写入另外100个文件。2)执行100文件匹配/合并,添加重复键整数值,并显示字符串键和整数值。@吉尔伯特-勒布朗。我同意步骤1,当第一次迭代时只允许加载2.5个文件时,如何实现步骤2?在随后的步骤中,文件数量要少得多。另外,当所有文件都具有唯一的字符串键值时,最坏的情况又如何呢pairs@bhava:您一次只保留内存中100个已排序文件的两行。您可以在读取文件时打印。这称为磁盘匹配/合并。这是我们40年前必须进行的处理。
    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()