C++ Rope数据结构&;线

C++ Rope数据结构&;线,c++,data-structures,text,ropes,C++,Data Structures,Text,Ropes,我正在使用存储库来存储大量(GB)的文本。文本可以长达数千万行 绳索本身在任何位置都能非常快速地插入,并且在特定位置也能快速获得角色 但是,如何获取特定行(\n在本例中)的起始位置?例如,如何获取第15行的起始位置?我可以看到几个选择 没有任何额外的数据。每当你想说第15行时,你就遍历绳子中的所有字符,找到换行符,当你到达第15行时,你就停下来 将每行的开始和长度存储在向量中。因此,您将拥有包含所有字符的Rope数据结构,然后是一个单独的std::vector。行结构只包含2个字段开始和长度。开

我正在使用存储库来存储大量(GB)的文本。文本可以长达数千万行

绳索本身在任何位置都能非常快速地插入,并且在特定位置也能快速获得角色

但是,如何获取特定行(
\n
在本例中)的起始位置?
例如,如何获取第15行的起始位置?我可以看到几个选择

  • 没有任何额外的数据。每当你想说第15行时,你就遍历
    绳子中的所有字符,找到换行符,当你到达第15行时,你就停下来
  • 将每行的
    开始
    长度
    存储在向量中。因此,您将拥有包含所有字符的
    Rope
    数据结构,然后是一个单独的
    std::vector
    结构只包含2个字段<代码>开始
    长度
    。开始表示线从
    绳索内部开始的位置,长度是线的长度。要获得第15行的起始位置,只需执行
    行[14]。开始
  • 问题

    #1是一种可怕的方式。这是非常缓慢的,因为你必须通过所有的字符

    #2也不好。虽然到达一行开始的位置非常快(
    O(1)
    ),但每次插入一行时,都必须将所有行移到它前面,这就是
    O(N)
    。此外,存储这意味着,对于您拥有的每一行,它将额外占用16字节的数据。(假设
    start
    length
    各为8个字节)。这意味着如果你有13000000行,它将占用200MB的额外内存。你可以使用链表,但它只会使访问速度变慢

    有没有更好、更有效的方法来存储行位置,以便快速访问和插入?(最好是
    O(log(n))
    用于插入和访问行)

    我曾考虑使用一个
    BST
    ,更具体地说,是一个,但我不完全确定如何使用它。我看到了
    VSCode
    do,但是使用了
    PieceTable

    任何帮助都将不胜感激

    编辑

    @interjay提供的答案似乎不错,但如果CR和LF在两个叶节点之间分割,我将如何处理CRLF

    我还注意到,它是
    绳索
    的锈蚀库。我想知道是否有类似的情况,但对于每个rope节点(叶子和内部节点)中的
    C++

    ,除了保存该子树中的字符数之外,还可以将包含在子树中的新行总数放在一起

    然后,查找特定换行符的方式与查找包含特定字符索引的节点的方式完全相同。您可以查看“换行数”字段,而不是“字符数”字段


    所有绳索操作的工作原理基本相同。创建新的内部节点时,只需添加其子节点的换行数。所有操作的复杂性是相同的。

    是否考虑将数据存储为表示行的字符串?@ StfHauluStand,对于连接、子串、插入等操作,不会有绳子的O(Logn)复杂度。它们都会取线性时间。谢谢答案!我要试试这个,然后报告回来我很好奇,如果这些线是CRLF,有两个叶节点,其中一个叶节点包含CR,另一个叶节点包含LF,我怎么知道它只有一条线而不是两条独立的线?@WowThere你可以只计算LF而忽略CRs。但是如果我计算CR,LF,那么CRLF呢?@WowThere我不认为这样做有什么好处。只要LFs就足以告诉你线路的起点。