【问题标题】:Building a string as a linked list将字符串构建为链表
【发布时间】:2012-11-15 20:40:10
【问题描述】:

如果我试图扫描一个未知长度的字符串,一次扫描一个字符并构建一个字符链表来创建字符串是否是一种好方法?我目前面临的唯一问题是我不确定如何在不要求用户一次输入一个字符的情况下一次处理一个字符的字符串,这是不合理的。有更好的方法吗?我想避免为了容纳大多数字符串而分配任意大尺寸的 char 数组。

【问题讨论】:

  • “我想避免为了容纳大多数字符串而分配任意大的字符数组。”你知道一个链表占用多少空间吗?我给你一个提示:很多。 (与字符相比)
  • 取决于,你打算用那个字符串做什么?
  • 不要使用scanf,使用getc(或getchar)。分配一个初始缓冲区,并将字符读入该缓冲区。当缓冲区已满时,使用realloc 扩大缓冲区。重复这个过程,直到你读完整个字符串。
  • 这主要用于学校实验室作业。我不确定输入字符串在标记程序测试时会有多大,所以我必须准备好适应任何大小。
  • @Lee 或者你可以使用getline...

标签: c string data-structures linked-list char


【解决方案1】:

暂时忽略 node-per-char 链接列表的过度使用内存,并假设您实际构建了它并将字符串放入其中。你真的可以使用它吗?

例如:

  • 非连续缓冲区意味着许多标准函数(例如printf()strlen()fwrite())根本不兼容或难以使用。
  • 对字符串进行非序列访问效率极低。

至于更好的方法:这实际上取决于您要对字符串做什么。 (例如,如果您可以在字符串传入时对其进行处理,那么您甚至不需要将整个内容保存在内存中。)

【讨论】:

    【解决方案2】:

    将它存储在一个数组中。使用固定大小的数组初始化数组,并在读取输入时将它们存储在数组中。当数组已满并且新输入出现时,然后创建一个更大的双倍大小数组,并将旧数组复制到新数组中。现在继续在这个数组中添加新的字符。重复该过程,直到您读取所有数据。您可以通过以下方法优化将字符从旧数组复制到新数组的过程

    1)Initialize a variable old_idx to 0
    2) When a new char comes (after the old array is full) then create a new array of double size of older one and copy the new char at old_size+1 index. Also copy the data at index old_idx in old array at old_idx in newer array.
    3)Increment old_idx
    

    最后只检查如果 old_idx

    整个过程的摊销成本非常低,这也是java中的ArrayList的工作原理。

    Array 相对于链表的优势显而易见

    1) Less memory footprint
    2)Faster linear access (as in array all the memory allocations for data happen in contiguous manner)
    

    【讨论】:

      【解决方案3】:

      在我的建议中,拥有一个字符链接列表将是一个非常糟糕的主意,因为它会为单个字符串消耗太多内存。

      相反,您分配一个标称大小的缓冲区(例如 128 字节)并继续读取字符。一旦你感觉缓冲区快满了,分配另一个两倍于当前大小的缓冲区并将第一个缓冲区的内容复制到第二个缓冲区,释放第一个缓冲区。像这样,你可以继续直到你的字符串被完全读取。

      另外,在我编写或看过的大多数程序中,都会保持字符串大小的上限,如果输入的字符串看起来超出大小,程序将返回错误。字符串大小的上限是根据应用程序上下文确定的。例如:如果您正在阅读的字符串是一个名称,它通常不能超过 32 个(或某个 x 值)字符,如果是这样,那么该名称将被截断以适应缓冲区。通过这种方式,缓冲区可以自己第一次分配到上限大小。

      这只是一个想法。可能有许多其他方法可以解决这个问题,而不是链表。

      【讨论】:

      • 基于链表的字符串实现在计算史上不时出现。您不会在节点中只放置一个字符,而是 4--32(仍然有很多开销,尤其是在低端)。他们提供的优势主要是在控制内存碎片方面,这在这个即使非常小的计算机也能负担得起完整服务操作系统的时代已经不是什么问题了。
      • @dmckee,我只是指提问者的解决方案。他将每个节点放置一个字符来维护字符串的想法对我没有吸引力。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-06
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多