Algorithm 如何从次线性空间/时间中的字符流计算回文?

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

我甚至不知道是否存在解决方案。下面是详细的问题。您是一个接受无限长字符流的程序(为简单起见,您可以假定字符为1或0)。在任何时候,我都可以停止流(比方说在N个字符通过之后),并询问您目前收到的字符串是否是回文。如何使用较少的次线性空间和/或时间来实现这一点。

可以使用一个或多个滚动哈希来提高精度。增量计算到目前为止读取的字符的散列,按照读取顺序和读取顺序相反

例如,如果您的哈希函数是
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页,可以在一个机构付费墙后面找到,我不会在别处转载。如果您愿意,可以联系作者以获得更详细的解释;我最近刚读到这篇文章,意识到这或多或少是你想要的。

第二轮

在我看来,每个新角色都有三种情况:

  • 角色打破潜在对称,例如,aab->aabc
  • 字符扩展中间,例如aab->aabb
  • 角色继续对称,例如aab->aaba
  • 假设您有一个指针跟踪字符串,并指向延续可能的回文的最后一个字符

    (我将使用括号表示指向的字符)

    假设您从aa(b)开始,并获得:

    • “a”(案例3),将指针移动到 左边,然后检查它是否是“a”(它是 是)。你现在有a(a)b
    • ‘c’(案例1),您不希望出现‘c’,在这种情况下,您从一开始就重新开始,现在有了aab(c)
    真正棘手的情况是2,因为不知何故你必须知道你刚得到的角色并没有影响对称性,它只是延伸了中间部分。为此,您必须保持一个额外的指针,跟踪平台(中间)边缘所在的位置。例如,您有(b)baabb,而您刚刚得到另一个“b”,在这种情况下,您必须知道重置指向中间平台底部的指针:bbaa(b)bb。因为我们要的是恒定的时间,所以首先你必须在这里拿一个指针(你没有时间搜索高原的边缘)。现在,如果你得到另一个“b”,你知道你仍然在这个平台的边缘,你把指针保持在它所在的位置,所以bbaa(b)bb->bbaa(b)bbb。现在,如果你得到一个“a”,你知道“b”不是扩展中间的一部分,你重置了两个指针(跟踪指针和边指针),所以你现在有了bbaabbbb((a))

    在这三个案例中,我认为所有的基础都包括在内。如果要检查当前字符串是否为回文,请检查第一个指针(不是平台的边缘指针)是否位于索引0处

    这可能会帮助您:

    如果存储最后的$k$多个输入符号,则可以轻松找到长度不超过$k$的回文。

    如果你使用论文中的算法,你可以找到回文的中点和回文长度的估计值

    一些想法。在每个回文中,所有字符的计数都是偶数,但在奇数长度回文中,中间字符的计数是奇数。此外,如果最后一个输入是回文,则下一个输入不能是回文,除非字符串中只有一个唯一字符。在某些情况下,你可以用这些来快速回答“否”,但我想不出一种方法来提高O(n)时间、空间以外的渐近复杂性。我可以理解想要使用小于O(n)空间,但O(n)时间似乎很奇怪,因为你需要对n个字符单独做一些事情。你的意思是,一旦水流停止,时间就不到O(n)秒了吗?@David:我想他就是这个意思是的,@wrick:我很难使用次线性空间。输入流可能是随机的(多达一半),并且仍然是回文,因此它最多有N/2个熵字符,这需要O(N)空间。当然,我可能错了。难道“阅读顺序相反”不需要你存储字符吗?我猜这是不确定的。。。如果你想要概率,你可以随机存储,比如n^0.9个字符(以及它们的位置),看看我们是否能在我们存储的内容中检测到回文…@Moron-你不必存储字符,因为哈希函数是多项式,所以你可以增量地构建这两个哈希。你说得对,这是概率的。但是,如果存储随机字符,是否会导致大量误报甚至误报?我会说这更准确,占用更少的内存。实际上,你的k像n一样增加