- 注册时间
- 2017-12-7
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 3243
- 在线时间
- 小时
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?欢迎注册
×
下面为方便描述,不妨用<01101>代指循环序列01101 01101 01101……
假设这里有许多循环节长度互素的01序列,问有没有什么有效的方法找到这几个序列中的0-1首次相等的位置。
比如这里有循环序列<1>,<10110>,<001>,<01>,即:
111111111111111111111111111111111111111111111111111111111111……
101101011010110101101011010110101101011010110101101011010110……
001001001001001001001001001001001001001001001001001001001001……
010101010101010101010101010101010101010101010101010101010101……
我们可以用肉眼看到,这几个序列从左往右数第6个元素都是1,所以这几个序列在第六个元素处首次相等
对付这个问题我的想法暂时只有全写出来用眼睛慢慢看(或者用计算机实现类似的算法)
想知道有没有更有效的算法(如果序列数量不多同时序列不长,可以用MITM进行攻击(比如如果只有3个序列而第一个序列是<1>,我们可以利用长序列构造一个中间序列,以减少多次查找带来的负担)),又或者这个题目到底会不会是NPC(反正我没想到如何构造各种逻辑门)
附一个长序列跟短序列跟<1>的说明
假设三个序列是<1><0000100010000100000100001001><100001000100001000001000010010000100010000100000100001000>
首先肉眼查不到
000010001000010000010000100100001000100001000001000010010000100010000100000100001001000010001000010000010000100100……
100001000100001000001000010010000100010000100000100001000100001000100001000001000010010000100010000100000100001000……
然而呢,我们应该观测到这样一个事实,不妨把短序列打头的0换成*
*000100010000100000100001001*000100010000100000100001001*000100010000100000100001001*000100010000100000100001001*0……
100001000100001000001000010010000100010000100000100001000100001000100001000001000010010000100010000100000100001000……
我们注意到,*对应的五个位置分别是1-1-0-0-0,*后面那个0对应的分布是0-1-0-0-0,这给了我们一种提示,如果我们可以把这样的序列之中,只要出现1的都改成1,以此制作中间序列(此时中间序列长度等于短序列长度),再拿得到的中间序列跟短序列比较,如果发现某一个位置这两个序列都是1,就说明短序列与长序列在短序列的这个位置上一定会相等,究竟何时相等可以做一次复查,反正上例不会超过5次。
当然,如果不相等,需要重算这样的中间序列——这里唯一的好处就是,当我们利用长序列计算中间序列的时候,长序列上面的每一个元素对应的中间序列元素的值是固定的,于是我们只需要计算一次中间序列,就可以反复利用中间序列与短序列进行比较。
理想情况下,短序列会重复(长序列循环节长度)次,我们对(长序列循环节长度)开根号,依此选取我们要的搜索长度,这样我们差不多需要(根号(长序列循环节长度))次搜索,而生成中间序列需要(根号(长序列循环节长度))次,这样可以极大地减少计算量。
算法看上去很好而且有改进空间,但无可避免的是,算法无论如何也需要遍历长序列,这样如果长序列的循环节很长,会出问题,而当<>的数量增加的时候,哪怕每一个<>的长度都不太长(比如只有几千),几十个这样的<>加起来构成的长序列已经超长太多了 |
|