两个循环缓冲区是否相等? (忽略转变)

时间:2014-11-06 12:26:53

标签: algorithm

我有两个循环缓冲区 - 如何判断一个是另一个循环?

例如B1 = 1,1,2,1,8,1,5,7B2 = 2,1,8,1,5,7,1,1我们可以说B1和B2相等,因为我可以旋转其中一个来获得另一个。

测试这种平等的最佳算法是什么?明显的测试是在O(n^2)中(只是比较缓冲区 - 以n步骤 - 从每个n元素开始)但我相信我已经看过线性时间算法。你能指点我吗?

2 个答案:

答案 0 :(得分:6)

假设B1B2的长度相同,那么您的问题就等于询问“B2B1 + B1的子字符串”(B11234连接在一起本身)。

例如:当且仅当12341234的子字符串为{{1}}时,4元素字符串才是{{1}}的旋转。

检查一个字符串是否是另一个字符串的子字符串可以使用KMP algorithm以线性时间完成。

答案 1 :(得分:0)

如果你的缓冲区是整数,我想也许你可以使用加法作为交换属性的事实(a+b == b+a) 这意味着列表的开头并不重要。但另一方面,项目的顺序为(1+2+3+4) = (3+1+2+4),以确保项目的顺序正确,我们可以成对或三联将它们关联起来。为了更好地确保链接顺序.. (12+23+34+41)或类似的东西..

var B1 = [1,1,2,1,8,1,5,7]
var B2 = [2,1,8,1,5,7,1,1]
var B3 = [2,1,8,1,5,7,1,4]

function checksum(buff)
{
    var sum = 0
    for(var i = 0 ; i < buff.length;i++)
    {
        var a  = buff[i];
        var b  = buff[(i+1)%buff.length];
        var c  = buff[(i+2)%buff.length];
        var n = ((a*100) + (b * 10) + c);
        sum += n;
    }
    return sum;
}
console.log(checksum(B1) == checksum(B2))//true
console.log(checksum(B1) == checksum(B3))//false

这是一个“订单敏感”的循环校验和

但是像每个哈希函数一样会出现冲突和误报,所以你仍然需要一个辅助的比较方法。

不知道我是否走在正确的轨道上..希望有人可以帮助让它更好或完全反驳..