使用数组的堆栈实现(改进代码)

时间:2019-09-22 11:44:31

标签: c++ stack

只需要使用数组来实现堆栈,方法是: push,pop,print 。 任务本身: 仅使用数组实现堆栈。编译器唯一应分配内存的时间是通过 set_size 函数。 当前的代码版本运行良好,但是我正在寻找改善执行时间/复杂性/可读性等的方法。有什么想法吗? 预先谢谢你。

#include <vector>
#include <string>

template <class T>
class Stack
{
 int size = 0;
 T* Array;
 int top = 0;

public:
 Stack(size_t Size);
 ~Stack()
 {
     delete[] Array;
 }
 void push(T element);
 void pop();
 void print();
};
template <class T>
Stack<T>::Stack(size_t Size)
{
 size = Size;
 top = -1;
 Array = new T[size];
}
template <class T>
void Stack<T>::push(T element)
{
 if (top >= (size - 1))
 {
     std::cout << "overflow" << std::endl;
 }
 else
 {
     Array[++top] = element;
 }
}
template <class T>
void Stack<T>::pop()
{
 if (top < 0)
 {
     std::cout << "underflow" << std::endl;
 }
 else
 {
     std::cout << Array[top--] << std::endl;
 }

}
template <class T>
void Stack<T>::print()
{
 if (top == -1)
 {
     std::cout << "empty" << std::endl;
 }
 int i = top;
 while (i > -1)
 {
     std::cout << Array[i--] << " ";
 }
 std::cout << std::endl;
}
template <class T>
Stack<T> set_size(int Size)
{
 return Stack<T>(Size);
}

int main()
{
 auto stack = set_size<std::string>(5);
 stack.push("hello");
 stack.push("hi");
 stack.push("hey");
 stack.push("greetings");
 stack.push("welcome");
 stack.print();
 stack.pop();
 stack.pop();
 stack.print();
 return 0;
}```

3 个答案:

答案 0 :(得分:0)

您的主要问题来自堆栈指针top与堆栈大小size之间的类型转换。

topint,它是一种带符号的类型。 size_t unsigned 整数类型。

在测试(top >= (size - 1))时,top被转换为unsigned int,然后被视为UINT_MAX而不是-1,而对于其他任何情况,该{>总是> = unsigned int

您可以使用size_t作为堆栈指针,这意味着您不能使用负值,也可以将(size - 1)转换为带符号的值,然后再与top进行比较(但最后一个解决方案意味着您必须确保指定为size_t的大小不太大,无法转换为带符号的int。)

您的打印功能也有两个问题:

  • 在您的第一个测试中,您将-1分配给top而不是比较值
  • 您更改了top堆栈指针,以便在调用print()之后,您的堆栈处于不一致状态

答案 1 :(得分:0)

与其在堆上分配数组,不如将其放在堆栈上。这是可能的,因为您可以将size作为模板参数传递。对于性能而言,这比堆上的内存要好。

我将使用size_t(无符号整数)作为大小类型,以使大小不能为负数;然后在您的push()函数中将其强制转换为int以与top进行比较。

template <typename T, size_t const Size>
class Stack
{
    private:
    T Array[Size];
    int top;

    public:
    Stack()
    {
        top = -1;
    }

    void push(T element)
    {
        if (top >= static_cast<int>(Size)-1)
        {
           std::cout << "overflow" << std::endl;
        }
        else
        {
            Array[++top] = element;
        }
    }

    void pop()
    {
         if (top < 0)
         {
             std::cout << "underflow" << std::endl;
         }
         else
         {
             std::cout << Array[top--] << std::endl;
         }
    }

    void print()
    {
        if (top < 0)
        {
           std::cout << "empty" << std::endl;
        }

        int i=top;
        while (top > -1)
        {
           std::cout << Array[i--] << " ";
        }
        std::cout << std::endl;
    }

};

现在,无需在类外部使用set_size函数。您可以像这样实例化一个实例:

Stack<std::string, 3> stack;

答案 2 :(得分:0)

  1. 您的分支预测可能不是最佳的。您应该检查生成的程序集,以查看预测在您的if结构中是else而非if...else上下注(它可能会预测if,在这种情况下您应该将常见情况放在if中。

  2. 您应该通过引用而不是通过值传递参数。对于简单的整数并不重要,但是如果您的T变得更复杂,则会在push上产生多余的副本。