我有两个循环缓冲区 - 如何判断一个是另一个循环?
例如B1 = 1,1,2,1,8,1,5,7
,B2 = 2,1,8,1,5,7,1,1
我们可以说B1和B2相等,因为我可以旋转其中一个来获得另一个。
测试这种平等的最佳算法是什么?明显的测试是在O(n^2)
中(只是比较缓冲区 - 以n
步骤 - 从每个n
元素开始)但我相信我已经看过线性时间算法。你能指点我吗?
答案 0 :(得分:6)
假设B1
和B2
的长度相同,那么您的问题就等于询问“B2
是B1 + B1
的子字符串”(B1
与1234
连接在一起本身)。
例如:当且仅当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
这是一个“订单敏感”的循环校验和
但是像每个哈希函数一样会出现冲突和误报,所以你仍然需要一个辅助的比较方法。
不知道我是否走在正确的轨道上..希望有人可以帮助让它更好或完全反驳..