【问题标题】:Coming up with simple formula for linked list想出简单的链表公式
【发布时间】:2011-02-28 02:18:57
【问题描述】:

老实说,我已经在这几天了。我已经实现了这个功能的困难部分,但现在只有一件小事。我想写的方法是删除链表的每个blockSize的第N个块。因此,如果我有一个大小为 7 {1,2,3,4,5,6,7}N=2blockSize=2 的链表,我想删除每个大小为 blockSize(2) 的 Nth(2nd) 块,所以删除 3、4、7。现在,为了让我的 for 循环正常工作,我需要为我创建的名为 numBlocksRemoved 的 int 值编写一个表达式。它计算要删除的块的总数。在这种情况下,它将是 2。这就是我所拥有的:

numBlockRemoved=(size/blockSize)/N;

但是,这仅在数字看起来不错的情况下有时才有效。如果我有size=8,N=2, blockSize=2,那么我会得到numBlockRemoved=2,这是正确的。但是,对于上面的示例,我得到的 int 值为 1,这是不正确的。我想要 2。我想了很久,这太荒谬了。我只是想不出一个适用于 numBlockRemoved 的公式。有什么想法吗?

【问题讨论】:

  • 对于链表,您不必提前计算。事实上,链表通常不知道它们的大小。相反,当您到达列表末尾时,您的循环应该结束。
  • 它是一个自定义的链表类。每个链表都有一个成员变量大小。

标签: c++ algorithm linked-list


【解决方案1】:

试试

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 因为你要么计算一个块,要么不计算。

【讨论】:

  • 这也不起作用。对于 size=7、N=2、blockSize=2,你得到 1,但应该是 2。
  • 不,这仍然不起作用。尝试 size=7,N=3,blockSize=2。应该是 1,但你的 yields 2
【解决方案2】:

在计算块数时舍入应该向上,因为不完整块仍然是块(但在计算移除块数时不是):

numBlockRemoved=((size+blockSize-1)/blockSize)/N;

【讨论】:

  • 不,这是不正确的。考虑 size=7,N=3,blockSize=2:你得到 numBlockRemoved=2,但它应该是 1。
  • 好的,你只需要向上舍入blockSize除法。我会修正我的答案。
【解决方案3】:

(size + (blockSize - 1)) / (blockSize * N)

【讨论】:

  • 不,考虑 size=3, N=2, blockSize=1
  • 我把blockSizeN 弄混了——现在就来看看吧。
【解决方案4】:

只要系统地考虑一下——如果你每取第 N 个大小为 blockSize 的块,你实际上是在删除大小为 (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 调整折叠到公式中,方法是添加一个数量,如果它小于一个街区,则该数量将使整个超级块的大小倾斜(类似于通过添加 0.5 然后取舍来四舍五入) )。因为如果我们在超级块的最后一个块中是偶数,就会发生这种情况,我们必须添加 (blockSize - 1),这给了我们

(size + (blockSize - 1)) / (blockSize * N)

上面是aaz的公式。因此,您可以继续将他的答案标记为已接受;我只是想解释一下他是如何得出这个公式的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    相关资源
    最近更新 更多