Stack C++

I have the following code. But the problem is, it only accepts one integer. They told me I have to write ONE stack that accept TWO integers. So basically, I'm stuck and in need of help.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  Stack::Stack() : topPtr(NULL)
{
}  // end default constructor

Stack::Stack(const Stack& aStack)
{
   if (aStack.topPtr == NULL)
      topPtr = NULL;  // original list is empty

   else
   {  // copy first node
      topPtr = new StackNode;
      topPtr->item = aStack.topPtr->item;

      // copy rest of list
      StackNode *newPtr = topPtr;    // new list pointer
      for (StackNode *origPtr = aStack.topPtr->next;
	   origPtr != NULL;
	   origPtr = origPtr->next)
      {  
         newPtr->next = new StackNode;
         newPtr = newPtr->next;
	 newPtr->item = origPtr->item;
      }  // end for

      newPtr->next = NULL;
   }  // end if
}  // end copy constructor

Stack::~Stack()
{
   // pop until stack is empty
   while (!isEmpty())
      pop();
   // Assertion: topPtr == NULL
}  // end destructor

bool Stack::isEmpty() const
{
   return topPtr == NULL;
}  // end isEmpty

void Stack::push(const StackItemType& newItem)
            throw(StackException)
{
   // create a new node
   try
   {
      StackNode *newPtr = new StackNode;

      // set data portion  of new node
      newPtr->item = newItem;

      // insert the new node
      newPtr->next = topPtr;
      topPtr = newPtr;
   }
   catch (bad_alloc e)
   {
      throw StackException(
	 "StackException: push cannot allocate memory.");
   }  // try
}  // end push

void Stack::pop() throw(StackException)
{
   if (isEmpty())
      throw StackException("StackException: stack empty on pop");
   else
   {  // stack is not empty; delete top
      StackNode *temp = topPtr;
      topPtr = topPtr->next;
      // return deleted node to system
      temp->next = NULL;  // safeguard
      delete temp;
   }  // end if
}  // end pop

void Stack::pop(StackItemType& stackTop) throw(StackException)
{
   if (isEmpty())
      throw StackException("StackException: stack empty on pop");
   else
   {  // stack is not empty; retrieve and delete top
      stackTop = topPtr->item;
      StackNode *temp = topPtr;
      topPtr = topPtr->next;

      // return deleted node to system
      temp->next = NULL;  // safeguard
      delete temp;
   }  // end if
}  // end pop

void Stack::getTop(StackItemType& stackTop) const throw(StackException)
{
   if (isEmpty())
      throw StackException("StackException: stack empty on getTop");
   else
      // stack is not empty; retrieve top
      stackTop = topPtr->item;
}  // end getTop 


Above is actually the .cpp file.
Last edited on
Wow, that much code for a stack?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
template <class T> class stack
{
    T* data;
    unsigned size_;

    public:
    stack() : size_(0){}
    stack(T initializer, unsigned times)
    {
        size_ = times-1;
        data = new T[times];
        for(int i = 0; i < times; i++) data[i] = initializer;
    }

    void push(T data_)
    {
        size_++;
        data = new T[size_];
        data[size_] = data_;
    }
    void pop()
    {
        size_--;
        data = new T[size_];
    }
    T top() const
    {
        return data[size_];
    }
    void clear()
    {
        for(unsigned i = 0; i < size_; i++)
        {
            data[i] = 0;
        }
    }
    bool empty() const
    {
        bool ret = true;
        for(unsigned i = 0; i < size_; i++)
        {
            if(data[i] != 0)
            {
                ret = false;
                break;
            }
        }
        return ret;
    }
    unsigned size() const
    {
        return size_;
    }
    void resize(unsigned newsize)
    {
        size_ = newsize;
        data = new T[size_];
    }
};

This can handle all size and all types.
Simple. Nothing to add. I think you can understand yourself.
Use one stack<std::pair<std::pair<int,int>,std::string>>
http://www.cplusplus.com/reference/utility/pair/
Tip: use typedef stack<std::pair<std::pair<int,int>,std::string>> your_special_stack_name
Last edited on
Okay, thank you. I will try for the rest of the mentioned functions.
Here, I corrected the stack class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <algorithm>
    template <class T> class stack
    {
        T* data;
        unsigned size_;

        public:
        stack() : size_(0){}
        stack(T initializer, unsigned times)
        {
            size_ = times;
            data = new T[times];
            for(int i = 0; i < times; i++) data[i] = initializer;
        }

        void push(T data_)
        {
            T* temp = new T[size_ + 1];
            std::copy(data, data+size_, temp);
            size_++;
            data = new T[size_];
            std::copy(temp, temp+size_, data);
            data[size_-1] = data_;
        }
        void pop()
        {
            T* temp = new T[size_-1];
            std::copy(data, data+(size_-1), temp);
            size_--;
            data = new T[size_];
            std::copy(temp, temp+size_, data);
        }
        T top() const
        {
            return data[size_-1];
        }
        void clear()
        {
            for(unsigned i = 0; i < size_; i++)
            {
                data[i] = 0;
            }
        }
        bool empty() const
        {
            bool ret = true;
            for(unsigned i = 0; i < size_; i++)
            {
                if(data[i] != 0)
                {
                    ret = false;
                    break;
                }
            }
            return ret;
        }
        unsigned size() const
        {
            return size_;
        }
        void resize(unsigned newsize)
        {
            size_ = newsize;
            data = new T[size_];
        }
    };

    int main()
    {
        stack<unsigned> A;
        A.push(10);
        A.push(2);
        std::cout << A.top() << "\n";
        A.pop();
        std::cout << A.top();
    }


It's not exception safe.
After our 20 PM's, I made your program. Cool, a flood fill program. I think you should change you topics name or even create a article. Ok, here's you code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <stdexcept>
using namespace std;

void flood_fill(vector<string>& file, int x, int y, char newchar, int x_len, int y_len, char oldchar = 0)
{
    if(!oldchar) oldchar = file[y][x];
    if(file[y][x] != oldchar)
    {
        return;
    }
    oldchar = file[y][x];
    file[y][x] = newchar;

    if(x > 0) flood_fill(file, x-1,y,newchar, x_len,y_len,oldchar); //left
    if(y > 0) flood_fill(file, x, y -1, newchar,x_len,y_len, oldchar); //up
    if(x < x_len-1) flood_fill(file, x+1, y, newchar,x_len,y_len, oldchar); //right
    if(y < y_len-1) flood_fill(file, x, y+1, newchar,x_len,y_len,oldchar); //down
}
int main(int argc, char* argv[])
{
    if(argc != 2) {std::cerr << "The syntax is program.exe file"; return -1;}
    ifstream file;
    string content;
    string input;
    vector<string> entire_file;
    vector<string> params;
    file.open(argv[1]);
    if(!file){ std::cout << "The inputed file is not available."; return -1;}
    while(getline(file,content))if(!content.empty())entire_file.push_back(content);
    while(true)
    {
        std::cout << "Enter x, y, and filler (-1 to quit): ";
        std::getline(std::cin, input);
        if(input == "-1") break;
        std::stringstream a (input);
        while(getline(a, input, ' '))
        params.push_back(input);
        try
        {
            std::stoi(params[0]);
            std::stoi(params[1]);
            if(params[2].size() != 1 || std::stoi(params[0]) < 0 || std::stoi(params[0]) > entire_file[0].size() || std::stoi(params[1]) > entire_file.size() || std::stoi(params[1]) < 0) throw std::invalid_argument("");
        }
        catch(...)
        {
            std::cout << "The syntax is x y filler. Make sure x and y are in limits.\n\n";
            return -2;
        }
        file.close();
        std::cout << "Filling ("<<params[0]<<","<<params[1]<<")\'"<<params[2]<<"\'\n";
        flood_fill(entire_file, std::stoi(params[0]), std::stoi(params[1]), params[2][0], entire_file[0].size(), entire_file.size());
        ofstream file_;
        file_.open(argv[1], ios_base::trunc);
        for(auto a : entire_file)
        {
            file_ << a << "\n";
        }
        break;
    }
    return 0;
}


Good easter!
PS: I caught that idea from this Python script: http://inventwithpython.com/floodfill/recursivefloodfill.py
Topic archived. No new replies allowed.