【问题标题】:Stacks implementation堆栈实现
【发布时间】:2013-01-25 21:33:04
【问题描述】:

我无法理解 push 和 pop 如何与堆栈一起工作。我了解它们是如何工作的,因为它们将一个数字推入堆栈,最后一个推入的数字将被弹出。我也理解指针背后的逻辑以及它们是如何工作的。我不明白的是代码应该如何编写。

我的程序应该让用户创建一个堆栈(确定它有多大),然后选择将内存(数字)压入堆栈或将其弹出。

这是我到目前为止得到的,我被困住了。我已经通过 cplusplus.com 进行了研究,并阅读了有关这些内容的几乎所有内容,但仍然无法弄清楚该程序应该如何布局以及如何运行。

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>

using namespace std;

int choice;
int * arrPtr = NULL;
int * stack;
int * top;
int val, capacity, size; 
//stack would point to the location of the first element,
// top would point to the location where the next element will be stored,
// capacity is the number of elements that can be stored in the stack,
// size would be the number of elements actually stored in the stack

int main()
{
//This is the menu
cout << "1. Create" << endl;
cout << "2. Push" << endl;
cout << "3. Pop" << endl;
cout << "4. Count" << endl;
cout << "5. Display" << endl;
cout << "6. Exit\n" << endl;
cin >> choice;

//I figured i would use choices for the menu and went ahead and wrote it out
switch(choice)
{
    case 1:
        create();
        break;
    case 2:
        push();
        break;
    case 3:
        pop();
        break;
    case 4:
        count(0);
        break;
    case 5:
        display();
        break;
    case 6:
        exit();
    default:
        cout << "Please enter correct choice (1-4)!";
        break;
    }

    return 0;   
}   //end main

void create()
{
    cout << "Enter the size of the stack you wish to create: ";
    int capacity = 0;
    cin >> capacity;

    arrPtr = new int[capacity];
} //end create function

//From here it went wrong, I cannot figure it out.           

void push(){
    for (int i = 0; i < capacity; i++)
    {
        cout << "Enter the number you wish to put on the stack: ";
        cin >> val;
        push(val)
    }//end for
}//end push

请帮助我理解这一点。

【问题讨论】:

  • 您使用动态内存分配进行堆栈实现的任何具体原因?
  • 用户应该创建堆栈大小

标签: c++ arrays stack


【解决方案1】:

我已经在 Mac 上编译了这段代码,但它应该可以在安装了 bash 的 PC 上的 Linux 上正常工作。

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>

using namespace std;

int choice;
int capacity; /*size of stack*/ 

int stack[1000];/*THIS IS WHERE ALL THE STACK ENTRIES WILL BE STORED*/
int top=0; /* THIS WILL KEEP CHECK OF THE INDEX OF TOP MOST ELEMENT */

//stack would point to the location of the first element,
// top would point to the location where the next element will be stored,
// capacity is the number of elements that can be stored in the stack,
// size would be the number of elements actually stored in the stack

void create() //Set size of stack
{
    cout << "Enter the size of the stack you wish to create: ";
    cin >> capacity;

} //end create function


void push(int n) //Enter data into stack

{

/* Ensures that there isn't a stack overflow */

    if(top<capacity)
    {
        stack[top++]=n; 
    }


    else
    {
        cout<<"Stack FULL!!\n";
    }

    //end for
}//end push

void pop() //Remove data from stack
{
    /* Ensures that there isn't a stack underflow */
    if(top>0)
    {
        cout<<"Popped entry is:"<<stack[top-1]<<"\n";
        top--;   
    }

    else
    {
        cout<<"Stack is EMPTY!!\n";
    }


}

void count() //Count number of elements
{
    cout<<"Stack size is:"<<top<<"\n"; 
}

void display() //Print elements from lowest stack entry to highest 
{
    int i=0;
    cout<<"Your stack is:\n";
    while(i<top)
    {
        cout<<i+1<<") "<<stack[i]<<"\n";
        i++;
    }
}



int main()
{
    system("clear");  //Start with blank screen



    int exitCheck=1,entry;

    //I figured i would use choices for the menu and went ahead and wrote it out -- This is good approach!!
    cout<<"Welcome user \n";

    create(); /*Size of stack can be set only once to prevent inconsistency */

    while(exitCheck == 1)  /* This is the menu */
    {

        cout << "1. Push" << endl;
        cout << "2. Pop" << endl;
        cout << "3. Count" << endl;
        cout << "4. Display" << endl;
        cout << "5. Exit\n" << endl;
        cin >> choice; //Choice should be placed here as we need userinput during each turn 

        switch(choice)
        {
            case 1:
                cout<< "Enter your data: ";
                cin>>entry;
                push(entry);
                break;
            case 2:
                pop();
                break;
            case 3:
                count();
                break;
            case 4:
                display();
                break;
            case 5:
                {
                    exitCheck=1;
                    break;
                } /*exit in this case wont achieve a proper result in a concole based app thats why i replaced it with loop exit condition */

            default:
                cout << "Please enter correct choice (1-5)!\n";
                break;
            }

        cout<< "Enter 1 to continue else anything else to quit:\n";
        cin>> exitCheck;


    }

    cout<<"Thanks for using this code!!\n";    
return 0;   
}
  //end main

【讨论】:

    【解决方案2】:

    使用std::vector的最简单堆栈

    #include <iostream>
    #include <vector>
    using namespace std;
    
    template<typename T>
    class Stack{
    private: 
      vector<T> theArray;
    public:
      Stack(){ theArray.clear(); }
      void push(T data) { theArray.push_back(data); }
      T pop() { T retData = theArray.back(); theArray.pop_back(); return retData; }
      void display() {
        for(size_t i = theArray.size() - 1; i != (size_t)-1; i--){
          cout << theArray[i] << '\n';
        }
      }
    };
    
    int main(int argc, char *argv[])
    {
      Stack<int> s;
      s.push(10);
      s.push(20);
      s.push(30);
      s.display();
    
      int ret = s.pop();
      cout << "After popping : " << ret << '\n';
      s.display();
      return 0;
    }
    

    【讨论】:

      【解决方案3】:

      创建std::array。创建迭代器。将迭代器设置为数组的末尾。 (结束含义array.end()

      推送:递减迭代器,插入值。
      Pop:返回值,递增迭代器。
      计数:不是堆栈的标准,但您可以通过从 end 中减去当前迭代器来获得它。
      窥视:返回值

      显然你想确保你没有从阵列的前面推开,或者从后面弹出,所以你应该添加一些检查。

      堆栈非常简单。希望这会有所帮助。

      编辑:实现,未测试的代码,有点思路

      template <typename T, std::size_t N>
      class Stack {
      public:
        Stack();
        void push(T value);
        T pop();
        T peek() const;
        std::size_t count() const;
      
      private:
        std::array<T, N> m_baseArray;
        std::array<T>::iterator m_it;
      };
      
      template <typename T, std::size_t N>
      Stack::Stack() : m_baseArray(), m_it(m_baseArray.end()) { }
      
      template <typename T, std::size_t N>
      void Stack::push(T value) {
        if (m_it == m_baseArray.begin())
          throw std::exception();
        --m_it;
        *m_it = value;
      }
      
      template <typename T, std::size_t N>
      T Stack::pop() {
        if (m_it == m_baseArray.end())
          throw std::exception();
        T res = *m_it;
        ++m_it;
        return res;
      }
      
      template <typename T, std::size_t N>
      T Stack::peek() const {
        if (m_it == m_baseArray.end())
          throw std::exception();
        return *m_it;
      }
      
      template <typename T, std::size_t N>
      std::size_t Stack::count() const {
        return m_baseArray.end() - m_it;
      }
      

      【讨论】:

      • Count 应该只是数组中元素的数量
      • std::array 似乎不是一个好的堆栈后端,因为它的大小必须在编译时知道(这意味着您要么只能处理小堆栈,要么分配大量可能浪费的记忆)。 std::vector 似乎是一个更好的选择,但如果不能使用(因为作业这么说等等),你将不得不回到 int[] 数组。 (或者使用一个动态数量的固定大小std::arrays,你保存在一个链表中......)
      • (不过,+1 因为对于给定最大大小的堆栈,方法和解释都很好!)
      • @Subhajit,抱歉,我不清楚 count 方法需要什么。
      • @us2012,好吧,堆栈传统上是在固定大小的容器中实现的,从后到前填充。也许双端队列是最好的选择。感谢您的 +1。
      猜你喜欢
      • 2010-11-27
      • 2013-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-07
      • 2019-11-11
      • 2017-07-27
      • 2012-04-07
      相关资源
      最近更新 更多