Algorithm 如何从次线性空间/时间中的字符流计算回文?
我甚至不知道是否存在解决方案。下面是详细的问题。您是一个接受无限长字符流的程序(为简单起见,您可以假定字符为1或0)。在任何时候,我都可以停止流(比方说在N个字符通过之后),并询问您目前收到的字符串是否是回文。如何使用较少的次线性空间和/或时间来实现这一点。可以使用一个或多个滚动哈希来提高精度。增量计算到目前为止读取的字符的散列,按照读取顺序和读取顺序相反 例如,如果您的哈希函数是Algorithm 如何从次线性空间/时间中的字符流计算回文?,algorithm,stream,puzzle,palindrome,Algorithm,Stream,Puzzle,Palindrome,我甚至不知道是否存在解决方案。下面是详细的问题。您是一个接受无限长字符流的程序(为简单起见,您可以假定字符为1或0)。在任何时候,我都可以停止流(比方说在N个字符通过之后),并询问您目前收到的字符串是否是回文。如何使用较少的次线性空间和/或时间来实现这一点。可以使用一个或多个滚动哈希来提高精度。增量计算到目前为止读取的字符的散列,按照读取顺序和读取顺序相反 例如,如果您的哈希函数是x*3^(k-1)+x*3^(k-2)+…+x*3^0,其中x是您读取的字符,您可以这样做: hLeftRight
x*3^(k-1)+x*3^(k-2)+…+x*3^0
,其中x
是您读取的字符,您可以这样做:
hLeftRight = 0
hRightLeft = 0
k = 0
repeat until there are numbers in the stream
x = stream.Get()
hLeftRight = 3*hLeftRight + x.Value
hRightLeft = hRightLeft + 3^k*x.Value
if (x.QueryPalindrome = true)
yield hLeftRight == hRightLeft
k = k + 1
很明显,你必须计算一些模的散列,可能是素数或二的幂。当然,这可能会导致误报。是的。答案大约是下降的三分之二 编辑:有些人要求我总结结果,以防链接失效。该链接提供了以下定理证明的一些细节:有一个多磁带图灵机,可以实时识别初始的非平凡回文。(本文也提供了一个摘要:假设机器读取了输入的x1,x2,…,xk。那么它只有恒定的时间来决定x1,x2,…,xk是否是回文。) 一台多点图灵机只是一台有几个并排磁带的机器,它可以读取和写入磁带;在一个非常具体的意义上,它完全等同于一个标准的图灵机 实时计算是指图灵机必须至少每M步从输入中读取字符一次(对于某些有界常数M)。很容易看出,任何实时算法都应该是线性时间的 有一篇关于证明的论文,大约有10页,可以在一个机构付费墙后面找到,我不会在别处转载。如果您愿意,可以联系作者以获得更详细的解释;我最近刚读到这篇文章,意识到这或多或少是你想要的。第二轮 在我看来,每个新角色都有三种情况:
- “a”(案例3),将指针移动到 左边,然后检查它是否是“a”(它是 是)。你现在有a(a)b
- ‘c’(案例1),您不希望出现‘c’,在这种情况下,您从一开始就重新开始,现在有了aab(c)
如果你使用论文中的算法,你可以找到回文的中点和回文长度的估计值 一些想法。在每个回文中,所有字符的计数都是偶数,但在奇数长度回文中,中间字符的计数是奇数。此外,如果最后一个输入是回文,则下一个输入不能是回文,除非字符串中只有一个唯一字符。在某些情况下,你可以用这些来快速回答“否”,但我想不出一种方法来提高O(n)时间、空间以外的渐近复杂性。我可以理解想要使用小于O(n)空间,但O(n)时间似乎很奇怪,因为你需要对n个字符单独做一些事情。你的意思是,一旦水流停止,时间就不到O(n)秒了吗?@David:我想他就是这个意思是的,@wrick:我很难使用次线性空间。输入流可能是随机的(多达一半),并且仍然是回文,因此它最多有N/2个熵字符,这需要O(N)空间。当然,我可能错了。难道“阅读顺序相反”不需要你存储字符吗?我猜这是不确定的。。。如果你想要概率,你可以随机存储,比如n^0.9个字符(以及它们的位置),看看我们是否能在我们存储的内容中检测到回文…@Moron-你不必存储字符,因为哈希函数是多项式,所以你可以增量地构建这两个哈希。你说得对,这是概率的。但是,如果存储随机字符,是否会导致大量误报甚至误报?我会说这更准确,占用更少的内存。实际上,你的k像n一样增加