【问题标题】:Any good techniques for Memory Usage optimization for maximum String input length针对最大字符串输入长度的内存使用优化的任何好的技术
【发布时间】:2017-04-11 17:19:36
【问题描述】:

我正在设计一个字符串算法,问题在于输入的大小。根据定义,Java 的最大字符串长度为 2147483647,以避免混淆 ~2.15x10^9。

根据定义,Manacher 算法需要一个字符数组:

char[n*2 +3] 其中 n 是输入的长度(大小为 n 的字符串)

根据定义,最大整数是上面提到的~2.15x10^9,所以字符数组可以是最大大小

char [ ~2.15x10^9 ];

这种在 java 中的 manachers 算法的计算,将输入字符串的限制降低到 n = (~2.15x10^9 - 3) / 2 。准确地说,就是 1073741822。~1.1x10^9。

一个最大长度的 char 数组有 (n*2) + 32 bytes = ( ~2.1x10^9 * 2 ) + 32 bytes = ~4.2x10^9 bytes (4.2GBs)

还有各种大小、集合和其他集合的附加数组。我相信这将使程序占用〜30GBs的整个空间。用于计算算法的最大 RAM 内存输入,我们确定该算法的长度最多为 ~1.1x10^9 个字符。

您能否建议我一些技巧,以使内容保持在“最长可能的字符串输入”和“内存管理”之间?谢谢

【问题讨论】:

  • 您确定您的算法需要一个 16 位 UTF-16 字符数组,而不是 字节 数组吗?
  • 您是否真的要在其上运行此算法的 4 GB 输入?听起来您刚刚接受了 Java 数组的绝对限制,并假设您的程序将在这些限制下运行。
  • 老实说,这不会为您节省超过 2 倍。老实说?处理限制;它们并不是特别糟糕。
  • @s_arabov:如果甚至存在内存问题,我会通过分析和查看我的程序最重的内存使用量实际来自哪里来接近它。如果存在内存问题,解决方案可能涉及在磁盘上保留更多数据,或者可能只是购买更多 RAM。
  • @GhostCat 该算法旨在寻找 DNA 和 RNA 字符串之间的关系

标签: java string algorithm


【解决方案1】:

根据this article,Manacher 算法在线性时间内找到最长的回文子串n 是原始字符串的长度)。

Here's an implementation in Java,这表明该算法在内存消耗方面也相当出色(您需要两个数组,一个是字符,另一个是整数,两者的长度都是原始字符串的两倍,并且您还需要存储原始字符串)。

问题是您的原始字符串非常长,因此您正在达到语言限制、内存限制等。

另一方面,您的字母表仅包含 7 个字符:原始字符串字符 A C T G,加上字母分隔符(例如 #)以及字符串字符的开头和结尾(例如 $ 和 @ 987654329@)。这意味着您只需要 3 位 来存储每个可能的字符。因此,如果您愿意使用位运算符位掩码,您可以在long中存储21个字符(这是因为long 用 64 位表示)。这种方法的代码会更复杂,但它会使用更少的内存。

另一个可能的解决方案是使用动态结构而不是字符串和数组。这些结构将使用大量内存,但它不是连续内存,这意味着您不会达到最大数组大小限制和整数等语言限制。这种方法使用suffix tree,根据this article , 是一种线性时间方法。在那篇文章中有一个 C++ 解决方案。祝你好运!

【讨论】:

  • 感谢您提供的信息,您的帖子对我帮助很大!核酸 ACTG 和 GUAC 非常适合我的目的,我将研究 C++ 后缀树的问题并使用位运算符和位掩码!再次非常感谢!
  • @s_arabov 不客气。你知道,有时候,成为一名开发人员并嫁给一名遗传学家真的很有帮助:)
猜你喜欢
  • 2020-07-10
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 2013-02-10
  • 1970-01-01
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多