我正在设计一个字符串算法,问题在于输入的大小。根据定义,Java的最大字符串长度为2147483647,以避免混淆~2.15x10 ^ 9.
Manacher的算法根据定义需要一个字符数组:
char[n*2 +3]
其中n是输入的长度(大小为n的字符串)
根据定义,最大整数是上面提到的~2.15x10 ^ 9,所以一个字符数组可以是最大尺寸
char [ ~2.15x10^9 ];
这种java中的管理算法计算,将输入字符串的限制降低到n =(~2.15x10 ^ 9 - 3)/ 2。准确地说就是1073741822.~1.1x10 ^ 9。
最大长度的字符数组有(n * 2)+ 32字节=(~2.1x10 ^ 9 * 2)+ 32字节= ~4.2x10 ^ 9字节(4.2GBs)
Theres其他各种大小,集合和其他集合的数组。我相信这将使该程序占用~~ 30GB的整个空间。用于最大输入RAM内存,用于计算我们最多识别为~1.1x10 ^ 9个字符的算法。
你能否告诉我一些技术,以便在“最长的字符串输入”和“内存管理”之间保持平衡?谢谢
答案 0 :(得分:2)
根据this article,Manacher算法在线性时间中找到最长的回文子串(其中n
是原始字符串的长度)。
Here's an implementation in Java,它表明该算法在内存消耗方面也相当不错(你需要两个数组,一个字符和一个整数,两个都是原始字符串的两倍,你还需要存储原始字符串)。
问题是您的原始字符串非常长,因此您达到了语言限制,内存限制等。
另一方面,您的字母表只包含7个字符:原始字符串字符A C T G
,加上字母分隔符(例如#
)以及字符串字符的开头和结尾(例如{ {1}}和$
)。这意味着您只需要 3位来存储每个可能的字符。因此,如果您愿意使用按位运算符和位掩码,则可以在@
中存储 21个字符(此是因为long
用64位表示。这种方法对代码来说会更复杂,但它会占用更少的内存。
另一种可能的解决方案是使用动态结构而不是字符串和数组。这些结构将使用相当大的内存,但它不会是连续的内存,这意味着你不会达到最大数组大小限制和int的语言限制等。这种方法使用suffix tree,根据{{3}},是一种线性时间方法。在那篇文章中,有一个C ++解决方案。祝你好运!