Skip to content

Commit 5c8214c

Browse files
authored
Update stack.cpp
I have updated this file by add implementation using linkedlist and array.
1 parent fc5ca10 commit 5c8214c

File tree

1 file changed

+197
-120
lines changed
  • pydatastructs/miscellaneous_data_structures/_backend/cpp/stack

1 file changed

+197
-120
lines changed
Lines changed: 197 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,224 @@
1-
#include <Python.h>
1+
#include <iostream>
22
#include <vector>
33
#include <stdexcept>
4-
#include "SinglyLinkedList.hpp"
5-
#include "DynamicOneDimensionalArray.hpp"
6-
7-
// Forward declarations for types in the module
8-
extern PyTypeObject ArrayStackType;
9-
extern PyTypeObject LinkedListStackType;
10-
11-
static struct PyModuleDef stackmodule = {
12-
PyModuleDef_HEAD_INIT,
13-
"_stack",
14-
"Stack Data Structure Module",
15-
-1,
16-
NULL
17-
};
18-
19-
// Stack base class (Abstract class)
20-
class Stack {
21-
public:
22-
virtual void push(PyObject* x) = 0;
23-
virtual PyObject* pop() = 0;
24-
virtual bool is_empty() = 0;
25-
virtual PyObject* peek() = 0;
26-
virtual Py_ssize_t __len__() = 0;
27-
virtual const char* __str__() = 0;
28-
};
29-
30-
// ArrayStack Implementation (Derived class)
31-
class ArrayStack : public Stack {
32-
public:
33-
std::vector<PyObject*> items; // Dynamic array to store items
34-
35-
ArrayStack() {}
36-
37-
ArrayStack(std::vector<PyObject*> initial_items) {
38-
items = initial_items;
39-
}
4+
#include <memory>
5+
#include <sstream>
6+
#include <typeinfo>
7+
8+
namespace pydatastructs {
9+
10+
// DynamicOneDimensionalArray implementation
11+
class DynamicOneDimensionalArray {
12+
private:
13+
std::vector<int> arr;
14+
15+
public:
16+
void append(int x) {
17+
arr.push_back(x);
18+
}
4019

41-
void push(PyObject* x) override {
42-
items.push_back(x);
43-
}
20+
int get_last_filled() const {
21+
if (arr.empty()) {
22+
throw std::out_of_range("Array is empty");
23+
}
24+
return arr.back();
25+
}
4426

45-
PyObject* pop() override {
46-
if (is_empty()) {
47-
throw std::out_of_range("Stack is empty");
27+
void delete_last() {
28+
if (arr.empty()) {
29+
throw std::out_of_range("Array is empty");
30+
}
31+
arr.pop_back();
4832
}
49-
PyObject* top_element = items.back();
50-
items.pop_back();
51-
return top_element;
52-
}
5333

54-
bool is_empty() override {
55-
return items.empty();
56-
}
34+
size_t size() const {
35+
return arr.size();
36+
}
5737

58-
PyObject* peek() override {
59-
if (is_empty()) {
60-
throw std::out_of_range("Stack is empty");
38+
std::string to_string() const {
39+
std::ostringstream oss;
40+
for (int val : arr) {
41+
oss << val << " ";
42+
}
43+
return oss.str();
6144
}
62-
return items.back();
63-
}
6445

65-
Py_ssize_t __len__() override {
66-
return items.size();
67-
}
46+
void set_dtype(const std::type_info& type) {
47+
// In the context of C++, we typically don't need to worry about dynamic types like in Python.
48+
}
49+
};
50+
51+
// SinglyLinkedList Node definition
52+
struct Node {
53+
int value;
54+
std::shared_ptr<Node> next;
55+
56+
Node(int x) : value(x), next(nullptr) {}
57+
};
58+
59+
// SinglyLinkedList implementation
60+
class SinglyLinkedList {
61+
private:
62+
std::shared_ptr<Node> head;
63+
size_t list_size;
64+
65+
public:
66+
SinglyLinkedList() : head(nullptr), list_size(0) {}
67+
68+
void append_left(int x) {
69+
auto new_node = std::make_shared<Node>(x);
70+
new_node->next = head;
71+
head = new_node;
72+
list_size++;
73+
}
6874

69-
const char* __str__() override {
70-
std::string result = "[";
71-
for (size_t i = 0; i < items.size(); ++i) {
72-
result += PyUnicode_AsUTF8(PyObject_Str(items[i]));
73-
if (i != items.size() - 1) {
74-
result += ", ";
75+
int pop_left() {
76+
if (head == nullptr) {
77+
throw std::out_of_range("List is empty");
7578
}
79+
int value = head->value;
80+
head = head->next;
81+
list_size--;
82+
return value;
7683
}
77-
result += "]";
78-
return result.c_str();
79-
}
80-
};
8184

82-
// LinkedListStack Implementation (Derived class)
83-
class LinkedListStack : public Stack {
84-
public:
85-
SinglyLinkedList stack; // Linked list to store the stack elements
85+
int head_value() const {
86+
if (head == nullptr) {
87+
throw std::out_of_range("List is empty");
88+
}
89+
return head->value;
90+
}
8691

87-
LinkedListStack() {}
92+
size_t size() const {
93+
return list_size;
94+
}
8895

89-
LinkedListStack(std::vector<PyObject*> initial_items) {
90-
for (auto& item : initial_items) {
91-
push(item);
96+
std::string to_string() const {
97+
std::ostringstream oss;
98+
auto current = head;
99+
while (current) {
100+
oss << current->value << " ";
101+
current = current->next;
102+
}
103+
return oss.str();
92104
}
93-
}
105+
};
106+
}
94107

95-
void push(PyObject* x) override {
96-
stack.appendleft(x);
97-
}
98108

99-
PyObject* pop() override {
100-
if (is_empty()) {
101-
throw std::out_of_range("Stack is empty");
109+
namespace pydatastructs {
110+
// Forward declaration of the SinglyLinkedList and DynamicOneDimensionalArray
111+
class DynamicOneDimensionalArray;
112+
class SinglyLinkedList;
113+
114+
enum class Backend { PYTHON, CPP };
115+
116+
// Abstract Stack class
117+
class Stack {
118+
public:
119+
virtual ~Stack() {}
120+
virtual void push(int x) = 0;
121+
virtual int pop() = 0;
122+
virtual bool is_empty() const = 0;
123+
virtual int peek() const = 0;
124+
virtual size_t size() const = 0;
125+
virtual std::string to_string() const = 0;
126+
};
127+
128+
// ArrayStack class for stack implementation using dynamic array
129+
class ArrayStack : public Stack {
130+
private:
131+
std::shared_ptr<DynamicOneDimensionalArray> items;
132+
133+
public:
134+
ArrayStack(std::shared_ptr<DynamicOneDimensionalArray> items) : items(items) {}
135+
136+
void push(int x) override {
137+
items->append(x);
102138
}
103-
return stack.popleft();
104-
}
105139

106-
bool is_empty() override {
107-
return stack.size() == 0;
108-
}
140+
int pop() override {
141+
if (is_empty()) {
142+
throw std::out_of_range("Stack is empty");
143+
}
144+
int top_element = items->get_last_filled();
145+
items->delete_last();
146+
return top_element;
147+
}
109148

110-
PyObject* peek() override {
111-
return stack.head;
112-
}
149+
bool is_empty() const override {
150+
return items->size() == 0;
151+
}
113152

114-
Py_ssize_t __len__() override {
115-
return stack.size();
116-
}
153+
int peek() const override {
154+
if (is_empty()) {
155+
throw std::out_of_range("Stack is empty");
156+
}
157+
return items->get_last_filled();
158+
}
117159

118-
const char* __str__() override {
119-
std::string result = "[";
120-
auto node = stack.head;
121-
while (node != nullptr) {
122-
result += PyUnicode_AsUTF8(PyObject_Str(node->data));
123-
if (node->next != nullptr) {
124-
result += ", ";
160+
size_t size() const override {
161+
return items->size();
162+
}
163+
164+
std::string to_string() const override {
165+
return items->to_string();
166+
}
167+
};
168+
169+
// LinkedListStack class for stack implementation using singly linked list
170+
class LinkedListStack : public Stack {
171+
private:
172+
std::shared_ptr<SinglyLinkedList> stack;
173+
174+
public:
175+
LinkedListStack(std::shared_ptr<SinglyLinkedList> stack) : stack(stack) {}
176+
177+
void push(int x) override {
178+
stack->append_left(x);
179+
}
180+
181+
int pop() override {
182+
if (is_empty()) {
183+
throw std::out_of_range("Stack is empty");
184+
}
185+
return stack->pop_left();
186+
}
187+
188+
bool is_empty() const override {
189+
return stack->size() == 0;
190+
}
191+
192+
int peek() const override {
193+
return stack->head_value();
194+
}
195+
196+
size_t size() const override {
197+
return stack->size();
198+
}
199+
200+
std::string to_string() const override {
201+
return stack->to_string();
202+
}
203+
};
204+
205+
// Stack factory function
206+
std::shared_ptr<Stack> create_stack(const std::string& implementation, std::shared_ptr<DynamicOneDimensionalArray> items = nullptr, Backend backend = Backend::CPP) {
207+
if (implementation == "array") {
208+
if (backend == Backend::CPP) {
209+
// Use C++ backend for array stack
210+
return std::make_shared<ArrayStack>(items);
211+
} else {
212+
// Use Python backend or default
213+
return std::make_shared<ArrayStack>(items);
214+
}
215+
} else if (implementation == "linked_list") {
216+
if (backend != Backend::PYTHON) {
217+
throw std::invalid_argument("Linked list stack requires Python backend.");
125218
}
126-
node = node->next;
219+
return std::make_shared<LinkedListStack>(std::make_shared<SinglyLinkedList>());
220+
} else {
221+
throw std::invalid_argument("Implementation not supported");
127222
}
128-
result += "]";
129-
return result.c_str();
130223
}
131-
};
132-
133-
// Python Module Initialization
134-
PyMODINIT_FUNC PyInit__stack(void) {
135-
PyObject *stack_module = PyModule_Create(&stackmodule);
136-
if (PyType_Ready(&ArrayStackType) < 0)
137-
return NULL;
138-
Py_INCREF(&ArrayStackType);
139-
PyModule_AddObject(stack_module, "ArrayStack", (PyObject*)&ArrayStackType);
140-
141-
if (PyType_Ready(&LinkedListStackType) < 0)
142-
return NULL;
143-
Py_INCREF(&LinkedListStackType);
144-
PyModule_AddObject(stack_module, "LinkedListStack", (PyObject*)&LinkedListStackType);
145-
146-
return stack_module;
147224
}

0 commit comments

Comments
 (0)