(这不是CS课程的家庭作业,即使它看起来像一个)
我使用位域来表示0到22之间的范围。作为输入,我有几个不同的范围,例如(顺序无关紧要)。我为.
使用0
,为X
使用1
以提高可读性。
.....XXXXX..............
..XXXX..................
.....XXXXXXXXXXXXXXX....
........XXXXXXX.........
XXXXXXXXXXXXXXXXXXXXXXXX
位域范围的数量通常低于10,但可能会高达100.从该输入,我想计算互斥的连续范围,如下所示:
XX......................
..XXX...................
.....X..................
......XX................
........XX..............
..........XXXXX.........
...............XXXXX....
....................XXXX
(同样,输出顺序无关紧要,它们只需要相互排斥和连续,即它们不能有空洞。.....XXX.......XXXXX....
必须分成两个单独的范围。 / p>
我尝试了几种算法,但所有这些算法都变得相当复杂和不优雅。有什么能帮助我的方法是检测.....XXX.......XXXXX....
有一个洞和一种确定洞中某个位的索引的方法。
编辑:位域范围代表地图上的缩放级别。它们旨在用于输出Mapnik的XML样式表(由OpenStreetMap使用的平铺渲染系统)。
答案 0 :(得分:0)
我会考虑你的子问题,至少......
什么能帮助我极大地发现这一点
.....XXX.......XXXXX....
有一个洞和一种确定索引的方法 洞中的一个位。
在位掩码中查找最低和最高位(“1”)位非常漂亮
解决问题;例如,请参阅glibc中的ffs(3)
,或参阅
例如http://en.wikipedia.org/wiki/Bit_array#Find_first_one
给定位图的第一个和最后一个索引,将其称为i
和j
,
您可以计算具有i
和j
设置的所有位的位图
使用M = ((1 << i) - 1) & (~((1 << j) - 1))
(对任何人道歉)
断接一个-错误)。
然后,您可以通过比较它来测试原始位图是否有孔
M
。如果它不匹配,您可以使用输入xor M
来查找
洞和重复。
答案 1 :(得分:0)
我假设您在评论中提到的解决方案是这样的:
从左侧或右侧开始(因此索引= 0),并扫描设置了哪些位(最多100次操作)。设置x的名称。还设置变量block = 0。
在index = 1时,重复并存储以设置y。如果x XOR y = 0,则两者都是相同的集合,因此转到index = 2。如果x XOR y = z!= 0,那么范围[block,index]是连续的。现在设置x = y,block = index,然后继续。
如果您有100个长度为22的位数组,则需要大约2200次操作。
这是一个最佳解决方案,因为无法进一步减少操作 - 在每个阶段,如果另一组与您的设置不匹配,您的范围会被破坏,因此要检查范围是否已损坏,您必须检查所有100位。