Stacks and Queues in order to test a palindrome - c++

I have made a custom Stack and Queue class. In my program I want to use them both to test out if a word or phrase is a Palindrome. However, I need to change in my Stack and Queue class, which will allow both numbers and strings. How would I go about this in a simple manner? I read up on people having trouble using Palindromes but that is with the and C++ reference class. Any ideas? Here is my code which works with numbers.
//Queue.h
#include <iostream>
using namespace std;
class Queue
{
public:
Queue();
~Queue();
void enqueue(int);
int dequeue();
void print();
private:
typedef struct Node {
Node *link_;
int item_;
} NODE;
NODE* head_;
};
Queue::Queue()
{
head_ = NULL;
}
Queue::~Queue()
{
if (head_ == NULL) return;
NODE *cur = head_;
while (cur) {
Node *ptr = cur;
cur = cur->link_;
delete ptr;
}
}
void Queue::enqueue(int n)
{
if (head_ == NULL) {
head_ = new NODE;
head_->item_ = n;
head_->link_ = NULL;
return;
}
NODE *cur = head_;
while (cur) {
if (cur->link_ == NULL) {
NODE *ptr = new NODE;
ptr->item_ = n;
ptr->link_ = NULL;
cur->link_ = ptr;
return;
}
cur = cur->link_;
}
}
void Queue::print()
{
if (head_ == NULL) return;
Node *cur = head_;
cout << "This is your current queue: " << endl;
while (cur) {
cout << cur->item_ << " ";
cur = cur->link_;
}
cout << endl;
}
int Queue::dequeue()
{
if (head_ == NULL) {
cout << "This is an empty queue!!" << endl;
return NULL;
}
NODE *tmp = head_;
int value = head_->item_;
if (head_->link_) {
head_ = head_->link_;
}
// pop the last element (head)
else {
delete tmp;
head_ = NULL;
}
cout << "You dequeued: " << value << endl;;
return value;
}
int getQueue()
{
Queue *que = new Queue();
que->enqueue(15);
que->enqueue(75);
que->enqueue(105);
que->enqueue(25);
que->enqueue(55);
que->print();
que->dequeue(); que->print();
que->dequeue(); que->print();
que->dequeue(); que->print();
que->dequeue(); que->print();
que->dequeue(); que->print();
que->dequeue(); que->print();
return 0;
}
I am really new into coding for C++ and really want to learn. If anyone could help me out it'll be much appreciated.

The best way to do this is to make your Queue type templated
template <typename T> class Queue
{
public:
Queue();
~Queue();
void enqueue(const T &value);
T dequeue();
void print();
private:
typedef struct Node {
Node *link_;
T item_;
} NODE;
NODE* head_;
};
Now you can use it as
Queue<int> intQueue;
intQueue.enqueue(1);
intQueue.enqueue(2);
int i = intQueue.dequeue();
Queue<string> stringQueue;
stringQueue.enqueue("hello");
Queue<char> charQueue;
charQueue.enqueue('c');

Related

reason why it doesn't works on visual 2019

I don't think there's a problem with coding grammar or composition. I drew it with my hands and checked it several times and found no particular problem. And I've tried this many times.
I tried to repeat over and over, but it just shuts down immediately without any output on the run window when I use the visual studio 2019 version. I've been Googling several times, but I can't find the solution I want.
Have I reinstall the visual program or have to manipulate extra options?
plz give some solutions
#include<iostream>
using namespace std;
#include<stdlib.h>
class Node {
public:
int data;
Node * next;
};
class Stack {
public:
Node *top;
Stack() {
top->next = NULL;
}
void push(int data);
int pop();
void show();
};
void Stack::push(int data)
{
Node *node = new Node;
node->data = data;
if (top->next == NULL) {
node->next = NULL;
top->next = node;
}
else {
node->next = top->next;
top->next = node;
}
}
int Stack::pop()
{
if (top-> next == NULL) {
cout << "stack empty" << endl;
return 0;
}
Node *temp = new Node;
temp = top->next;
int data = temp->data;
top->next = temp->next;
delete temp;
return data;
}
void Stack::show() {
Node *cur = new Node;
cur = top-> next;
while (cur != NULL) {
cout << cur-> data << "->";
cur = cur-> next;
}
}
int main() {
Stack s;
s.push(5);
s.push(1);
s.push(3);
s.show();
cout << endl;
cout << s.pop() << endl;
s.show();
return 0;
}
In your constructor
Stack() {
top->next = NULL;
}
top has never been given a value, so top->next is an error.
Looks to me that most of your code would be fixed if you replaced top->next with top throughout.
There's another error here
void Stack::show() {
Node *cur = new Node;
cur = top-> next;
You assign cur to a new node and then you forget about that and assign it to something else on the very next line. Just do this
void Stack::show() {
Node *cur = top-> next;
(but top-> next should really just be top as explained above).
and the same error here
Node *temp = new Node;
temp = top->next;
why assign a new node to temp if on the very next line you assign something else to temp?
Here's your code will all the bugs fixed (I think)
class Stack {
public:
Node *top;
Stack() {
top = NULL;
}
void push(int data);
int pop();
void show();
};
void Stack::push(int data)
{
Node *node = new Node;
node->data = data;
node->next = top;
top = node;
}
int Stack::pop()
{
if (top == NULL) {
cout << "stack empty" << endl;
return 0;
}
Node *temp = top;
int data = temp->data;
top = temp->next;
delete temp;
return data;
}
void Stack::show() {
Node *cur = top;
while (cur != NULL) {
cout << cur-> data << "->";
cur = cur-> next;
}
}

How to get below linked list with friend operator to working?

I am trying to execute linked list with the below code.But I am unable to figure out the mistake in it.
I got the concept of it but I am failing to implement the same.
Any help is highly appreciated.
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
Node(int j) : data(j), next(nullptr) {}
friend ostream &operator<<(ostream &os, const Node &n) {
cout << "Node\n"
<< "\tdata: " << n.data << "\n";
return os;
}
};
void addElement(Node **head, int data){
Node *temp = nullptr;
temp->data = data;
temp->next=nullptr;
Node *cur = *head;
while(cur) {
if(cur->next == nullptr) {
cur->next = temp;
return;
}
cur = cur->next;
}
};
void printList(const Node *head){
const Node *list = head;
while(list) {
cout << list;
list = list->next;
}
cout << endl;
cout << endl;
};
void deleteList(Node *head){
Node *delNode =nullptr;
while(head) {
delNode = head;
head = delNode->next;
delete delNode;
}};
int main() {
Node *list = nullptr;
addElement(&list, 1);
addElement(&list, 2);
printList(list);
deleteList(list);
return 0;
}
after compiling I am getting no error and no output.So I am unable to figure what is going wrong or else my implementation of which is not right!
Here an error straightaway
void addElement(Node **head, int data){
Node *temp = nullptr;
temp->data = data;
temp is null, but you dereference it. It's an error to dereference a null pointer.
I guess you meant this
void addElement(Node **head, int data) {
Node *temp = new Node(data);
which allocates a new Node, initialises it with data and makes temp point to the newly allocated Node.

Seg fault Queue using Linked List (C++)

The following is a new programmer's attempt at a Queue. It seg faults in the Push() function, when I try to print the data in the first node. Looks like front_ptr is not actually getting set in head_insert. What am I doing wrong here, is this a completely wrong approach?
Thanks.
#include <cstdlib>
#include <iostream>
using namespace std;
class node {
public:
typedef double data_type;
node(data_type init_data = 0, node * init_next = NULL) {
data = init_data;
next_node = init_next;
}
void set_data(data_type new_data) { data = new_data; }
void set_next(node * new_next) { next_node = new_next; }
data_type get_data() { return data; }
node * get_next() { return next_node; }
private:
data_type data;
node * next_node;
};
void head_insert(node::data_type val, node* head_ptr) {
node* insert_ptr = new node(val, head_ptr);
head_ptr = insert_ptr;
}
void list_insert(node::data_type val, node* prev_ptr) {
node* insert_ptr = new node(val, prev_ptr->get_next());
prev_ptr->set_next(insert_ptr);
}
void head_remove(node* head_ptr) {
node* remove_ptr = head_ptr;
head_ptr = head_ptr->get_next();
delete remove_ptr;
}
void list_remove(node * prev_ptr) {
node* remove_ptr = prev_ptr->get_next();
prev_ptr->set_next(remove_ptr->get_next());
delete remove_ptr;
}
void list_clear(node* head_ptr) {
while (head_ptr != NULL) {
head_remove(head_ptr);
}
}
class queue {
public:
queue() {
size = 0;
front_ptr = NULL;
rear_ptr = NULL;
}
//~queue() {}
bool empty() { return (size == 0);}
void push(node::data_type val) {
if (empty()) {
head_insert(val, front_ptr);
cout << "Here: " << front_ptr->get_data() << endl;
rear_ptr = front_ptr;
}
else {
list_insert(val, rear_ptr);
}
size++;
}
void pop() {
if (!empty()) {
head_remove(front_ptr);
size--;
}
}
private:
node* front_ptr;
node* rear_ptr;
int size;
};
int main() {
cout << "START" << endl;
double testVal = 1;
queue* qList = new queue();
qList->push(testVal);
cout << "END" << endl;
return 0;
}
Any help is greatly appreciated.
Your front_ptr remains null pointer in push, because head_insert accepts it by value. Dereferencing null pointer then crashes the program. Make parameters that you want to be modified by a function reference parameters like void head_insert(node::data_type val, node*& head_ptr).
Also, you can avoid crash of null pointer dereferencing by checking it before, for example like that:
cout << "Here: " << (front_ptr ? front_ptr->get_data() : 0./0.) << endl;

how can i get the front or top element of a vector queue?

I didn't put the full code because it was very long and i only need help with the small portion which is the **** area. i can't seem to use front() or top() to get the top element of the queue. I tried making top() function List keep getting error : 1) class List has no memeber named 'top' which means i don't have a function top in List, when i make it it says 2) no match for 'operator=' in printer_cpu[i] = SList::top() with T=PCB]()'
template <class T>
class node{
public:
T data;
node *next;
};
template <class T>
class List{
node<T> *head;
node<T> *tail;
public:
List()
{
head = tail = NULL;
}
bool isEmpty()
{
if(head == NULL) return true;
else return false;
}
void enqueue(T new_data){
node<T> *temp = new node<T>;
temp->data = new_data;
temp->next = NULL;
if(isEmpty()){
head = temp;
tail = temp;
}
else{
tail->next = temp;
tail = temp;
}
}
void dequeue(){
if(isEmpty())
{
cout << "The list is already empty" << endl;
}
node<T>* temp;
if(head == tail){
temp->data=head->data;
delete head;
head = tail = NULL;
}
else{
temp->data = head->data;
head = head->next;
delete temp;
}
}
node<T> top() // need help here ****
{
return head;
}
void display(){
node<T> *current = head;
while(current != NULL){
cout << current->data << endl;
current = current->next;
}
}
};
struct PCB
{
int ProcessID;
int ProcessorSize;
int priority;
string name;
};
typedef List<PCB> printing;
typedef List<PCB> disk;
void gen(vector<printing> &printer_queue,string printer_name[], int printers)
{
for(int i = 0; i < printers; i++)
{
int num = i+1;
ostringstream convert;
convert << num;
printer_name[i] = "p" + convert.str();
printer_queue.push_back(printing());
}
int main()
{
int numOfPrinter = 5;
string interrupt;
cin >> interrupt;
PCB cpu;
PCB printer_cpu[numOfPrinter];
string printer_name[numOfPrinter];
vector<printing> PQ;
gen(PQ,printer_name,numOfPrinter);
for(int i = 0; i < numOfPrinter; i++)
{
if(interrupt == printer_name[i])
{
cout << "Enter a name for this printer file: " << endl;
cin >> cpu.name;
PQ[i].enqueue(cpu);
printer_cpu[i] = PQ[i].top(); //need help here ****
}
}
}
It looks like you're missing an asterisk, because you need to return of type pointer, because that's what head is.
You should have
node<T> * top()
{
...
}
You also need to overload the = operator, because you are trying to compare type PCB with type node *.
Well, I compile your code successfully after correcting some mistakes.
I didn't meet class List has no memeber named 'top' problem.
Then your top() function returns the value of head, so you should change it to: node<T>* top() because head is a pointer to node<T>.
And the reason you got no match for 'operator=' error is that printer_cpu[i]'s type is PCB while PQ[i].top()'s type should be node<T>*
I have also found that the code you post lacks a } just before int main().

Singly-Linked List Add Function - Read Access Violation

I'm trying to create a basic singly-linked list using a separate Node class and LinkedList class. I barely know what I'm doing as I've just started learning C++, so any help would be greatly appreciated.
The LinkedList part of the code runs on its own, but I'm sure there are some corrections to be made there too. My main problem is that, when trying to add to the linked list, I'm getting (at line 64 of LinkedList.h):
Exception thrown: read access violation. this->head was nullptr.
I'm using Microsoft Visual Studio 2015. Here's the code:
LinkedList.h (it's inline):
#pragma once
#include <iostream>
using namespace std;
class Node
{
private:
Node *next = NULL;
int data;
public:
Node(int newData) {
data = newData;
next = NULL;
}
Node() {
}
~Node() {
if(next)
delete(next);
}
Node(int newData, Node newNext) {
data = newData;
*next = newNext;
}
void setNext(Node newNext) {
*next = newNext;
}
Node getNext() {
return *next;
}
int getData() {
return data;
}
};
class LinkedList
{
private:
Node *head;
int size;
public:
LinkedList()
{
head = NULL;
size = 0;
}
~LinkedList()
{
}
void add(int numberToAdd)
{
head = new Node(numberToAdd, *head);
++size;
}
int remove()
{
if (size == 0) {
return 0;
}
else {
*head = (*head).getNext();
--size;
return 1;
}
}
int remove(int numberToRemove)
{
if (size == 0)
return 0;
Node *currentNode = head;
for (int i = 0; i < size; i++) {
if ((*currentNode).getData() == numberToRemove) {
*currentNode = (*currentNode).getNext();
return 1;
}
}
}
void print()
{
if (size == 0) {
return;
}
else {
Node currentNode = *head;
for (int i = 0; i < size; i++) {
cout << currentNode.getData();
currentNode = currentNode.getNext();
}
cout << endl;
}
}
};
List Tester.cpp
// List Tester.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "LinkedList.h"
using namespace std;
int main()
{
LinkedList myList;
myList.add(4);
system("pause");
}
You are making copies where you should not:
This:
Node(int newData, Node newNext) {
data = newData;
*next = newNext;
}
should be:
Node(int newData, Node* newNext) {
data = newData;
next = newNext;
}
Because now this:
head = new Node(numberToAdd, *head);
becomes this:
head = new Node(numberToAdd, head);
and will work even if head is a null pointer. You may need to adjust your other code accordingly.
Your whole implementation is full of errors. It should look more like this instead:
#pragma once
#include <iostream>
class Node
{
private:
int data;
Node *next;
public:
Node(int newData, Node *newNext = NULL)
: data(newData), next(newNext)
{}
void setNext(Node *newNext) {
next = newNext;
}
Node* getNext() {
return next;
}
int getData() {
return data;
}
};
class LinkedList
{
private:
Node *head;
int size;
public:
LinkedList()
: head(NULL), size(0)
{
}
~LinkedList()
{
Node *currentNode = head;
while (currentNode)
{
Node *nextNode = currentNode->getNext();
delete currentNode;
currentNode = nextNode;
}
}
void add(int numberToAdd)
{
head = new Node(numberToAdd, head);
++size;
}
bool remove()
{
Node *currentNode = head;
if (!currentNode)
return false;
head = currentNode->getNext();
delete currentNode;
--size;
return true;
}
bool remove(int numberToRemove)
{
Node *currentNode = head;
Node *previousNode = NULL;
while (currentNode)
{
if (currentNode->getData() == numberToRemove)
{
if (head == currentNode)
head = currentNode->getNext();
if (previousNode)
previousNode->setNext(currentNode->getNext());
delete currentNode;
return true;
}
previousNode = currentNode;
currentNode = currentNode->getNext();
}
return false;
}
void print()
{
Node *currentNode = head;
if (!currentNode) return;
do
{
std::cout << currentNode->getData();
currentNode = currentNode->getNext();
}
while (currentNode);
std::cout << std::endl;
}
};
Which can then be simplified using the std::forward_list class (if you are using C++11 or later):
#pragma once
#include <iostream>
#include <forward_list>
#include <algorithm>
class LinkedList
{
private:
std::forward_list<int> list;
public:
void add(int numberToAdd)
{
list.push_front(numberToAdd);
}
bool remove()
{
if (!list.empty())
{
list.pop_front();
return true;
}
return false;
}
bool remove(int numberToRemove)
{
std::forward_list<int>::iterator iter = list.begin();
std::forward_list<int>::iterator previous = list.before_begin();
while (iter != list.end())
{
if (*iter == numberToRemove)
{
list.erase_after(previous);
return true;
}
++previous;
++iter;
}
return false;
}
void print()
{
if (list.empty()) return;
std::for_each(list.cbegin(), list.cend(), [](int data){ std::cout << data });
std::cout << std::endl;
}
};