Реализация задачи с использованием стека с++
Задача: разделить стек на 2 стека. В одном - чётные числа, в другом - нечётные. Запутался с реализацией функции просмотра верхушки стека с извлечением. Подскажите, где я ошибся.
#include <iostream>
using namespace std;
struct Stack{
int info;
Stack* head;
}*b,*t;
struct EvenStack {
int info;
EvenStack* head;
}*begin1,*t1;
struct OddStack {
int info;
OddStack* head;
}*begin2,*t2;
Stack* push(Stack* p, int n) {
Stack* t = new Stack;
t->info = n;
t->head = p;
return t;
}
int View( Stack* p, int n) {
int temp = t->info;
p = p->head;
delete t;
return temp;
}
EvenStack* pushEven(EvenStack *p, int n) {
EvenStack* t1 = new EvenStack;
t1->info = n;
t1->head = p;
return t1;
}
OddStack* pushOdd(OddStack* p, int n) {
OddStack* t2 = new OddStack;
t2->info = n;
t2->head = p;
return t2;
}
void OddPrint(OddStack *begin2) {
cout << "Odd Stack: ";
OddStack* r = begin2;
while (r != NULL) { cout << r->info << " "; r = r->head; }
}
void EvenPrint(EvenStack* begin1) {
cout << "Even Stack: ";
EvenStack* r = begin1;
while (r != NULL) { cout << r->info << " "; r = r->head; }
}
int main()
{
setlocale(0, "");
int n=0, k, i = 0;
cout << "Введите количество элементов: ";
cin >> k;
cout <<"Введите элементы: "<<endl;
while (i < k) {
cin >> n;
b =push(b,n);
cout << "Положили в стек:" <<n<< endl;
i++;
}
while (t != NULL) {
int x = View(b,n);
if (x % 2 == 0) { begin2 = pushOdd(begin2, x); cout << "Положили в чётный стек:" << x << endl; }
else { begin1 = pushEven(begin1, x); cout << "Положили в нечётный стек:" << x << endl;
};
}
EvenPrint(begin1);
OddPrint(begin2);
}
Ответы (1 шт):
Ваша проблема в том, что вы пытаетесь три раза решить одну и ту же задачу. Скорее всего, при написании кода вы почувствовали, что повторяете код (возможно даже использовали ctrl+c ctrl+v). Повторение кода это важный сигнал того, что вы делаете что то не то и вам нужно остановиться и еще раз подумать о решении задачи.
Я так понял, что вы хотите создать два стека - в одном четные числа, а в другом нечетные. Что такое стек?
Стек (англ. stack — стопка; читается стэк) — абстрактный тип данных, представляющий собой список элементов, организованных по принципу LIFO (последний пришел - первый ушел)
В нашем случае важно то, что стек это сущность, которая не зависит от типа элементов. (Действительно, в определении не сказано, какого типа должны быть элементы). Нет определенного отдельного стека для строк, отдельного стека для целых чисел или отдельного стека для четных целых чисел. Есть просто стек, у которого элементами могут быть либо строки, либо целые число и т.д.
Вы пытались создать отдельный стек для четных чисел и отдельный стек для нечетных. Я предлагаю создать стек, а потом (в зависимости от нужд) помещать туда все, что необходимо.
Реализуем просто стек для целых чисел:
#include <iostream>
using namespace std;
//структура - элемент стека
struct StackItem
{
StackItem* next = nullptr; //хранит указатель на следующий элемент
int data;
};
//добавляем новый элемент на вершину стека
StackItem* push(StackItem* top, int var)
{
StackItem* new_top = new StackItem;
new_top->data = var;
new_top->next = top;
top = new_top;
return top;
}
//удаляем вершину стека и возвращаем значение.
StackItem* pop(StackItem* top)
{
if (top == nullptr) return 0;
auto old_top = top;
top = old_top->next; //теперь вершина - следующий элемент
delete old_top;
return top;
}
void print(StackItem* top)
{
auto iter = top;
while (iter != nullptr) //если iter == nullptr - дошли до конца стека
{
std::cout << iter->data << ' ';
iter = iter->next; //вывели значений, переходим к следующему элементу
}
std::cout << '\n';
}
int main()
{
StackItem* top = nullptr;
top = push(top, 5);
print(top);
top = pop(top);
print(top);
}
Элемент стека - StackItem у себя в хранит данные(int) и указатель на следующий элемент. Реализованы базовые функции работы с таким стеком - push и pop. Советую разобраться в коде. Теперь, при необходимости, можно создать два стека:
StackItem *oddTop = nullptr, eventTop = nullptr;
oddTop = push(oddTop, 5); //помещаем нечетные
eventTop = push(eventTop, 4); //помещаем четные
И нечетные и четные числа являются целочисленными и легко ложатся в тип int. Однако наш стек все таки оказался зависимым от типа элементов (например в него нельзя положить строку).
Если решать задачу дальше, то можно отойти от привязки к типу, добавив шаблонов.
template <typename T> //объявили шаблон с именем типа T
struct StackItem
{
StackItem<T>* next = nullptr; //хранит указатель на следующий шаблонный элемент типа StackItem<T>
T data; //хранит элемент типа T
};
template <typename T>
StackItem<T>* push(StackItem<T>* top, const T& var) //добавили шаблонную функцию push
{
StackItem<T>* new_top = new StackItem<T>;
new_top->data = var;
new_top->next = top;
top = new_top;
return top;
}
StackItem<int>* int_stack; //стек, где элементами являются целочисленные значения
StackItem<double>* double_stack;
StackItem<std::string>* string_stack;
push(int_stack, 5);
push(string_stack, "Hello");
В приведенном выше коде мы "отвязались" от типа в StackItem и в функции push. Теперь они будут работать для всех типов(с оговорками). Во время компиляции происходит инстанцирование (=подстановка) шаблонных методов и классов, т.е. компилятор смотрит какие типы используются для шаблонных методов и генерирует необходимый код. Мы используем класс StackItem для типов int, double, string - компилятор создаст код для трех классов и вместо 'T' подставит int, double и string. Также будет создан добавочный код для функции push для типов int и string (для double не будет создан код, тк мы не вызвали соответствующий метод push).
Следующей итерацией будет создание класса Stack, который будет хранить указатель на вершину (StackItem) и иметь методы push, pop, вывод на экран и тд