【问题标题】:Popping an item off the top of a circular array contained in a quack (queue/stack)从 quack(队列/堆栈)中包含的圆形数组顶部弹出一个项目
【发布时间】:2014-12-21 13:13:33
【问题描述】:

我目前正在尝试编写一个实现 quack(队列/堆栈)的程序。在 quack 的每个实例中,我都有一个指向字符数组“项目”的指针。我已经编写了 pushBackpushFront 函数,但是我编写了 popFrontpopBack 函数并意识到在这种情况下我不知道如何从数组中取消引用元素。

我的老师为我提供了一个文本文件,说明程序的输出应该是什么样子,并且它需要看起来与他的完全相同。在他的输出文件中,当字符从数组的前面或后面弹出时,它仍保留在内存中的那个位置,只是不再被数组使用。因此,当我将索引位置从数组的前面或后面弹出时,我不能将它设置回最初初始化的位置。该字符需要留在那里,所以当我运行代码时,即使它已从数组中弹出,它仍然会显示出来,直到有东西被推到覆盖它的数组上(数组的容量是静态的)。

注意:我的程序正在创建并写入一个单独的文本文件,该文件显示从数组当前前面到后面的数组元素,而不是从 items[0] 到 items[capacity-1],并且一旦从数组中弹出该字符,该文件就不会打印该字符。

我有一个名为 front 的 int 变量,它包含数组的当前前索引位置,还有一个名为 back 的 int 变量,它具有数组后面的索引位置数组。在尝试编写我的 popFront 函数时,我尝试做类似的事情

delete[] &items[front];

这没有用,也没有

delete[front] items;

让您了解我正在尝试做什么。我不知道我需要使用什么语法来完成这项工作。我将在此处为您提供更多代码,以便您自己查看:

Quack 构造函数:(是的,我必须将数组中的元素初始化为 '-' 因为 这就是他们在输出文件中还没有被分配一个字母时需要的样子)。此外,如果我想对这个赋值进行更困难的版本并使数组动态化,则为扩大数组的growBy 提供了实现,但我没有时间做那个所以你可以忽略@987654330 @。

Quack::Quack(int capacity, int growBy) :
    capacity(capacity),
    growBy(growBy),
    nItems(0),
    items(new char[capacity]),
    front(NULL),
    back(NULL)
{
    for (int i = 0; i < capacity; i++)
    {
        items[i] = '-';
    }
}

这是我的 Quack 类:(我在 Quack 类中省略了 printArray 函数,因为它冗长且无关紧要)

class Quack
{
public:

    Quack(int capacity, int growBy = 0);
    // capacity: # of slots in array
    // growBy:   # of slots to add to array when it grows, 0 means "don't grow"

    ~Quack(void);
    bool pushFront(const char ch);      // push an item onto the front
    bool pushBack(const char ch);       // push an item onto the back
    bool popFront(char& ch);            // pop an item off the front
    bool popBack(char& ch);             // pop an item off the back
    void rotate(int r);                 // "rotate" the stored items (see note below)
    void reverse(void);                 // reverse the order of the stored items
    int itemCount(void);                // return the current number of stored items

private:
    char    *items;                     // pointer to storage for circular array,
                                            // each item in the array is a char
                                        // items is an array with 

    int     nItems;                     // # of items currently stored in array
    int     capacity;
    int     growBy;                     // # of slots in array
    int     front;
    int     back;

public:
    friend std::ostream& operator<<(std::ostream& out, Quack *q);
};

最后,这就是我对popFront 所做的事情(你可以看到元素取消引用需要去哪里;剩下的就是我在弹出项目后将前面更改为正确的地方)。 itemCount() 是一个只返回 nItems 的函数,它是列表中的项目数,我也在跟踪。

bool Quack::popFront(char& ch)
{
    // if list is empty, can't pop
    if (itemCount() == 0)
    {
        return false;
    }

    // pop front item

    /* here is where I don't know what to do, stackoverflow */

    // increment front and nItems
    if (front < (capacity - 2))
    {
        front++;
        nItems--;
        return false;
    }
    else if (front == (capacity - 1))
    {
        front = 0;
        nItems--;
        return false;
    }
    return false;
}

这是 VS 中程序的正确输出,因此您可以看到它应该做什么:

(popFront 弹出列表前面的项目,popBack 弹出列表后面的项目, pushFront 将项目添加到列表的前面,pushBack 将项目添加到列表的后面)

pushFront(a)       [ a - - - - - - ]
pushFront(b)       [ a - - - - - b ]
pushFront(c)       [ a - - - - c b ]
pushFront(d)       [ a - - - d c b ]
pushBack(z)        [ a z - - d c b ]
pushFront(e)       [ a z - e d c b ]
popFront -> e      [ a z - e d c b ]
popFront -> d      [ a z - e d c b ]
pushBack(f)        [ a z f e d c b ]
pushBack(g)        [ a z f g d c b ]
rotate(2)          [ a z f g c b b ]
rotate(-3)         [ a z f g g c b ]
reverse            [ b c g g f z a ]
pushFront(y)       [ b c g y f z a ]
rotate(3)          [ b c g y f z a ]
rotate(-4)         [ b c g y f z a ]
popBack -> c       [ b c g y f z a ]
popBack -> b       [ b c g y f z a ]
popBack -> a       [ b c g y f z a ]
popBack -> z       [ b c g y f z a ]
popBack -> f       [ b c g y f z a ]
popBack -> y       [ b c g y f z a ]
popBack -> g       [ b c g y f z a ]

还有一点需要注意:我没有抛出任何异常的原因是因为我没有在其中包含任何队列实现。我仅有的库是 fstream、iostream、ostream 和 iomanip(据我所知,根据作业的要求,我无法包含任何其他库)。

似乎没有像 quack 或 quackException 这样的保留术语,所以在我抛出 queueException 的情况下,我只返回 false(我假设这就是函数是 bool 类型的原因,我想不出任何其他原因:我们得到了函数原型,只是没有函数定义)。

非常感谢您的宝贵时间,哦,聪明的人!

【问题讨论】:

  • 对不起,尽管有卷心菜博士
  • delete[] 不适用于数组的单个元素。您需要将所有替代元素 shuffle 移回一个位置以消除要删除的元素并相应地更改顶部标记。
  • “庸医”是否与deque、出队或双端队列相同?

标签: c++ arrays stack queue


【解决方案1】:

您的变量items 是一个数组。你可以delete整个数组:

delete [] items;

或者不是delete,你不能分段删除一个元素。

【讨论】:

  • 一定有办法做到这一点?此作业已在 cs 课程中使用多年
  • 您不需要重新分配数组。那是矫枉过正。您只需要跟踪“前”和“后”的位置。
  • "当字符从数组的前面或后面弹出时,它会保留在内存中的那个位置," -- 你不应该在 push 或 pop 中删除数组,只是像@Barry 说的那样修改数组的逻辑末端。
【解决方案2】:

ch 是通过引用 &amp; 传递的,这意味着如果你给它赋值,那么这个值就会赋给传递给函数的变量。如果没有&amp;,作为参数传递的值将被复制到ch,如果您更改ch,则不会对原始参数产生任何影响。

分配给引用类似于分配给普通变量。引用指向与内存中另一个变量相同的数据,但它不是指针。一个引用只能“指向”另一个变量一次,但一个指针可以被多次指向。

这是一个例子:

// A silly example, which doubles the variable passed in
void doubleValue( int& i ) {
    i = i * 2;
}

// Sample use:
int j = 2;
doubleValue( j ); // j is now 4
doubleValue( j ); // j is now 8

因此,如果您需要返回 ch 中弹出的值,您可以使用数组访问,就像您通常从数组中获取值一样。

char sample = items[front];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2013-03-20
    • 2020-10-12
    相关资源
    最近更新 更多