【问题标题】:c++ Implementation of a combined queue/stackc++ 组合队列/堆栈的实现
【发布时间】:2014-10-24 05:26:46
【问题描述】:

对于我最近的家庭作业,我应该实现一个“quack”,它是循环队列和堆栈的组合。 现在,我正试图围绕前两个函数 pushFront 和 pushBack。 以下是它们如何工作的示例。

pushFront(a) [a-----]

pushFront(b) [a----b]

反之,如果先调用pushBack,则需要将item放在数组的第一个元素中,然后再往回移动。

pushBack(a) [a-----]

pushBack(b) [ab----]

这是我感到困惑的地方:

1.) 使用模运算将前面从 item[0] 包装到 item[max -1]。我能想到的唯一解决方案是创建一个 if 语句,该语句在达到 [0] 时向前移动到 [max-1]。

2.) 为了让 pushBack 函数将值放在 item[0] 中,它必须从 item[max-1] 开始(然后在放置项目之前“向后”移动)。问题是,如果首先调用 pushFront,则该位置已经有一个项目。

3.)我考虑过使用 while(item[back] != null) 来移动它,但是我稍后编写的 pop 函数似乎并没有真正从数组中删除项目。相反,他们只是移动前后位置,实际上是为了缩短嘎嘎声。 感谢您的帮助,如果您出于任何原因想查看代码,请告诉我。因为我的问题更具概念性,所以我认为这可能是解决问题的最佳方式。

【问题讨论】:

    标签: c++ stack queue


    【解决方案1】:

    您的架构有些混乱。我从您的解释中了解到,您有一个固定大小的 max 元素缓冲区,并且您必须在前面和后面添加元素。

    为了在这样一个循环缓冲区中执行此操作,您需要知道哪个是first active element and which is the last。所以你必须跟踪两个索引:startend。困难在于连续的活动元素可以跨越缓冲区的边界(即开始元素的索引高于结束元素的索引。

    empty: 
    +----+----+----+----+
    !    !    !    !    !     start=0, end=0
    ---------------------
    pushback(a):  
    +----+----+----+----+
    ! a  !    !    !    !     start=0, end=1
    ---------------------
    pushback(b):
    +----+----+----+----+
    ! a  !  b !    !    !     start=0, end=2
    ---------------------
    pushfront(c):
    +----+----+----+----+
    ! a  !  b !    ! c  !     start=max-1, end=2
    ---------------------
    
    after a log of push and pop front and back :
    +----+----+----+----+
    !    !  x ! y  ! z  !     start=1, end=0
    ---------------------
    

    1) 为了优雅地规避这些情况,模算术有助于:

    如果(end + 1) % max 小于max0 如果它正好是max,则结果为end+1。模运算符% 对于管理一种循环算术非常实用。

    2) 考虑到这个观点,你的回击是(伪代码):

    check that buffer is not full 
    add the element at end index and increment the index as explained in 1.  
    

    pushfront 在某种意义上是相似的,您必须在开始时或开始之前添加一个元素(取决于结构是空的还是已经有元素)并减少开始(因此提示:使用无符号整数类型,例如作为索引的 size_t,以便在从 0 递减时能够使用模数)。

    事实上你也有堆栈操作,这意味着你

    3) 考虑到这个逻辑,3 应该不再是一个问题。

    4) 但是有一个未解决的问题需要您考虑:

    当遵循这个逻辑时,一开始你有end==start,两个都是0。当你的结构将满时,end==start 再次,所以你必须考虑如何处理这个问题。产生差异的最简单方法是对元素进行计数。

    【讨论】:

    • 是的,我想我其实已经在这个之下了。不过谢谢。出现困难是因为前面和后面的位置必须从同一个地方开始,因为任何一个都可以用来将第一项添加到数组中。也为可怕的格式感到抱歉,我不知道如何在 cmets 中换行。哦等等,我完全只是用那个评论回答了我自己的问题。我的问题是我试图在添加项目之前移动前面或后面,我应该添加项目然后移动它。
    • 事实上,如果您需要从同一个地方开始,那么当队列为空时,后推和前推并不完全对称(我做了一个编辑来澄清)。
    • 感谢您的帮助。我又遇到了一个问题。在 start 和 end 之前插入项目会导致这种情况 pushFront(a) [a---] (start = max-1) pushBack(b) [b----] (end = 1) 。但是,在插入之前移动 start 和 end 需要 start 从 items[1] 开始, end 从 item[max-1] 开始。
    【解决方案2】:

    我相信函数 pushFront 应该将下一个字符推到列表的前面。所以而不是

    pushFront(a) [a-----]

    pushFront(b) [a----b]

    你应该得到,

    pushFront(a) [a-----]

    pushFront(b) [ba----]

    pushFront(c) [cba---]

    pushBack(d) [cbad--]

    无论哪种方式,在您需要找到正面和背面之前,您都不需要使用模运算符。

    【讨论】:

    • 虽然直觉上你会这么想,但实际上并非如此。我基本上只是从作业要求中复制了它。如果首先调用 pushFront 或 PushBack,它们应该将该项目存储在 item[0] 中。然后 pushFront 将项目存储在递减的位置,而 pushBack 将项目存储在递增的位置。
    猜你喜欢
    • 2021-07-08
    • 2010-12-20
    • 2020-06-12
    • 1970-01-01
    • 2014-12-23
    • 2010-10-15
    • 1970-01-01
    • 2010-11-26
    • 2012-09-12
    相关资源
    最近更新 更多