我老实说已经好几天了。我已经实现了这个功能的难点部分,但现在只有一件小事。我想写的方法是删除链表的每个第N块blockSize。因此,如果我有一个大小为7 {1,2,3,4,5,6,7}
,N=2
,blockSize=2
的链接列表,我想删除每个大小为blockSize(2)的第N个(第二个)块,所以删除3,4 ,7。现在为了使我的for循环工作,我需要为我创建的名为numBlocksRemoved的int值编写一个表达式。它计算要删除的块总数。在这种情况下,它将是2.这就是我所拥有的:
numBlockRemoved=(size/blockSize)/N;
但是,这只有在数字看起来不错的情况下才有效。如果我有size=8,N=2, blockSize=2
,那么我会得到numBlockRemoved=2
,这是正确的。但是,对于上面的例子,我得到int值为1,这是不正确的。我想要2.我已经考虑过这个太长时间的荒谬了。我只是想不出一个适用于numBlockRemoved的公式。有什么想法吗?
答案 0 :(得分:3)
尝试
floor(ceil(size/blockSize)/N)
floor(ceil(7/2)/3) = 1
floor(ceil(7/2)/2) = 2
floor(ceil(8/2)/2) = 2
您拥有的街区数量:
blocks = ceil(size/blockSize)
ceil
因为你不介意没有完整的块。
然后你跳过每一个N,所以:
floor(blocks/N)
floor
,因为你要么算一个块,要么你不算。
答案 1 :(得分:2)
当计算块数时,舍入应该是向上的,因为不完整的块仍然是块(但是在计算已移除块的数量时不是这样):
numBlockRemoved=((size+blockSize-1)/blockSize)/N;
答案 2 :(得分:1)
(size + (blockSize - 1)) / (blockSize * N)
答案 3 :(得分:0)
只要系统地考虑它 - 如果你采用每个第N个块大小的块大小,你就可以有效地删除大小的“超级块”(N * blockSize)。所以,对于第一个近似,你有
nBlocks = floor [size / (N * blockSize)]
现在,从您的示例中,即使您最后没有获得完整的阻止,您仍然希望将其删除。如果删除最后一个完整块后的余数超过(N-1)个完整块,则会发生这种情况。所以算法是
superblock = N * blockSize
nBlocks = floor (size / superblock)
remainder = size - (nBlocks * superblock)
if remainder > (N - 1) * blockSize {
nBlocks += 1
}
您可以将最后的+1调整折叠到公式中,方法是添加一个数量,如果它小于一个街区,则会将大小超过一个完整的超级块(类似于通过添加.5进行舍入然后发言)。因为如果我们在超级块的最后一个块中只有一个数字,我们必须添加(blockSize - 1),这给了我们
(size + (blockSize - 1)) / (blockSize * N)
以上是aaz的公式。所以你可以继续把他的答案标记为已被接受;我只想解释他是如何达到这个公式的。