2

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

4

3 回答 3

2

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

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

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

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

于 2012-11-28T04:01:21.440 回答
1

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

例如:

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

至于更好的方法:这真的取决于你要对字符串做什么。(例如,如果您可以处理传入的字符串,也许您甚至不需要将整个内容保存在内存中。)

于 2012-11-28T06:50:16.123 回答
0

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

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 < old_array_size 然后复制其余的旧数据。

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

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

1) Less memory footprint
2)Faster linear access (as in array all the memory allocations for data happen in contiguous manner)
于 2012-11-28T04:12:45.877 回答