How to reverse a queue and display it - c++

I have made a queue class and I have a queue and I want to reverse it,however when I implement the function it doesn't display anything.
Here's it
void reverse(Queue <T> &queue) {
if(!queue.empty())
{
int temp=queue.queue_front;
queue.pop(queue.queue_front);
reverse(queue);
queue.push(temp);
}
}
The pop function I'm using requires a value,that's why there is queue.queue_front.I'm trying to do it with a recursion.Here's my print function
void display() {
for(int current = queue_front+1; current < queue_length; current++)
{
cout << "[" << current << "]=" << queue_array [current] << " ";
}
}
Now that's what I'm doing in the main function
Queue <int>queue1(10);
queue1.push(16);
queue1.push(14);
queue1.push(6);
queue1.push(60);
queue1.reverse(queue1);
queue1.display();
Here's the pop function
void pop(T& item) {
if (empty()) {
cout << "The Queue is empty!";
exit(1);
}
else {
queue_front = (queue_front + 1) % queue_size;
item = queue_array[queue_front];
queue_length--;
}
}
It doesn't display anything.Thanks.

You're testing with a queue of integers, which hides quite a few bugs.
You should have tested with a Queue<std::string>.
First, here:
int temp=queue.queue_front;
you're saving an index, not an element.
What you intend must be
T temp = queue.queue_array[queue.queue_front];
but there's no reason to mess with member variables (see below).
Here,
queue.pop(queue.queue_front);
you're passing a reference to the queue's member to pop.
The parameter to pop is where the top element is stored after it's popped.
In other words, after that line, queue.queue_front will be the element that was at the front of the queue, not the index of the new front of the queue.
This would probably work:
void reverse(Queue <T> &queue) {
if(!queue.empty())
{
T temp;
queue.pop(temp);
reverse(queue);
queue.push(temp);
}
}

Related

How to index array of pointers to arrays [queue]?

I am trying program a queue with arrays in C++.
I used this approach https://stackoverflow.com/a/936709/7104310 as shown below.
My question: How can I index the arrays to fill them?
In a normal 2d-array it would be arr[3][2] for example. But I do not know how to do this with pointers. The question hat not been answered in the Solution upon.
Thank you!
#include <iostream>
#define MAX_SIZE 3
using namespace std;
// ary[i][j] is then rewritten as
//arr[rear*capacity + front]
// Class for queue
class msg_queue
{
char **arr; // array to store queue elements
int capacity; // maximum capacity of the queue
int front; // front points to front element in the queue (if any)
int rear; // rear points to last element in the queue
int count; // current size of the queue
public:
msg_queue(int size = MAX_SIZE, int slot_length = MAX_SIZE); // constructor
void dequeue();
void enqueue(char x);
char peek();
int size();
bool isEmpty();
bool isFull();
};
// Constructor to initialize queue
msg_queue::msg_queue(int size, int slot_length)
{
arr = new char*[size];
for (int i = 0; i < size; ++i) {
arr[i] = new char[slot_length];
}
capacity = size;
front = 0;
rear = -1;
count = 0;
}
// Utility function to remove front element from the queue
void msg_queue::dequeue()
{
// check for queue underflow
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
cout << "Removing " << arr[front] << '\n';
front = (front + 1) % capacity;
count--;
}
// Utility function to add an item to the queue
void msg_queue::enqueue(char item)
{
// check for queue overflow
if (isFull())
{
cout << "OverFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
cout << "Inserting " << item << '\n';
rear = (rear + 1) % capacity;
arr[rear] = item; //ERROR HERE
count++;
}
// Utility function to return front element in the queue
char msg_queue::peek()
{
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
return arr[front]; //ERROR HERE
}
Well, it's still arr[3][2].
Although arrays are not pointers, the way we use them is effectively using a pointer because of the way they work and the way their name decays.
x[y] is *(x+y), by definition.
That being said, I would recommend you drop the 2D dynamic allocation (which is poison for your cache) and create one big block of Width×Height chars instead. You can use a little bit of maths to provide 2D indexes over that data.
Also you forgot to free any of that memory. If you use a nice std::vector to implement my suggested 1D data scheme (or even if you hire a vector of vectors, but ew!) then it'll be destroyed for you. Of course if you could do that then you'd probably be using std::queue…

Vector does not accept new element properly

I see some odd behaviour in the code below. My console is printing
0lo1lo
when in reality I am expecting
0Hel1lo
Node.cpp
std::vector<Node> Node::getChildren() {
return children;
}
void Node::setChildren(std::vector<Node> childrenNodes) {
children = childrenNodes;
}
void Node::addChild(Node child) {
children.push_back(child);
std::cout << child.getTitle();
}
std::string Node::getTitle() {
return title;
}
From Main function
Node root = Node("root");
root.addChild(Node("Hel"));
root.addChild(Node("lo"));
std::cout << "\n";
std::vector<Node> children = root.getChildren();
for (int i = 0; i < children.size(); i++) {
Node menuItem = children[i];
std::cout << i;
std::cout << menuItem.getTitle();
}
std::cout << "\n";
Does anybody have an idea why getChildren() appears to be getting a vector that is not accurately listing the first element I inserted?
You're using global variables to store instance data:
std::string title;
That means there's only one title in your program and if you ever change it, it changes for every class, function, etc. that accesses it.
Make it a non-static member variable of Node and your problem will go away.

Insertion error in Binary Search tree

void BST::insert(string word)
{
insert(buildWord(word),root);
}
//Above is the gateway insertion function that calls the function below
//in order to build the Node, then passes the Node into the insert function
//below that
Node* BST::buildWord(string word)
{
Node* newWord = new Node;
newWord->left = NULL;
newWord->right = NULL;
newWord->word = normalizeString(word);
return newWord;
}
//The normalizeString() returns a lowercase string, no problems there
void BST::insert(Node* newWord,Node* wordPntr)
{
if(wordPntr == NULL)
{
cout << "wordPntr is NULL" << endl;
wordPntr = newWord;
cout << wordPntr->word << endl;
}
else if(newWord->word.compare(wordPntr->word) < 0)
{
cout << "word alphabetized before" << endl;
insert(newWord,wordPntr->left);
}
else if(newWord->word.compare(wordPntr->word) > 0)
{
cout << "word alphabetized after" << endl;
insert(newWord, wordPntr->right);
}
else
{
delete newWord;
}
}
So my problem is this: I call the gateway insert() externally (also no problems with the inflow of data) and every time it tells me that the root, or the initial Node* is NULL. But that should only be the case before the first insert. Each time the function is called, it sticks the newWord right at the root.
To clarify: These functions are part of the BST class, and root is a Node* and a private member of BST.h
It's possible it is quite obvious, and I have just been staring too long. Any help would be appreciated.
Also, this is a school-assigned project.
Best
Like user946850 says, the variable wordPntr is a local variable, if you change it to point to something else it will not be reflected in the calling function.
There are two ways of fixing this:
The old C way, by using a pointer to a pointer:
void BST::insert(Node *newWord, Node **wordPntr)
{
// ...
*wordPntr = newWord;
// ...
}
You call it this way:
some_object.insert(newWord, &rootPntr);
Using C++ references:
void BST::insert(Node *newWord, Node *&wordPntr)
{
// Nothing here or in the caller changes
// ...
}
To help you understand this better, I suggest you read more about scope and lifetime of variables.
The assignment wordPntr = newWord; is local to the insert function, it should somehow set the root of the tree in this case.

C++ HW Help using stack

I am a little stuck on how to use the stack and why I would even use stack in the code I am writing. The assingment says to write a program that checks if the user input is well-Iformed or not. It is a simple prgram that has three different selections the use can choose from. 1. basic brackets () 2. standard brackets ()[]{} and 3. User-definded brackets. The only thing the main program is suppose to do is to check if the users input is well-formed or not and display only that message on the screen.
I have a StackLS.cpp and a Stack.h file I am using along with my main.cpp. I will paste a sample code below from each.
StackLS.h
typedef int elemType; // flexible data type
class StackLS
{
private:
// inner class node
class Node
{
public:
elemType data; // data portion
Node *next; // link to the seccessor
}; // end Node
// data members
Node *topItem; // pointer to the top element of this stack
// utilities
public:
// constructors
StackLS(void); // default constructor
StackLS(const StackLS& aStack); // copy constructor
// observers
bool isEmpty(void) const;
// returns true if this stack is empty
// false otherwise
bool isFull(void) const;
// returns true if this stack is full
// false otherwise
elemType top(void) const;
// precondition: this stack is not empty
// returns top element in this stack
// transformers
void push(const elemType& item);
// precondition: this stack is not full
// adds item to this stack
void pop(void);
// removes top element from this stack if exist
// remains empty otherwise
void makeEmpty(void);
// makes this stack empty
// destructor
~StackLS(void);
}; // end StackLS
StackLS.cpp
// constructors
StackLS::StackLS(void)
// default constructor
{
topItem = 0;
} // end default constructor
StackLS::StackLS(const StackLS& aStack)
// copy constructor
{
} // end copy constructor
// observers
bool StackLS::isEmpty(void) const
// returns true if this stack is empty
// false otherwise
{
return topItem == 0;
} // end isEmpty
bool StackLS::isFull(void) const
// returns true if this stack is full
// false otherwise
{
return false;
} // end isFull
elemType StackLS::top(void) const
// precondition: this stack is not empty
// returns top element in this stack
{
// return (*topItem).data;
return topItem->data;
} // end top
// transformers
void StackLS::push(const elemType& item)
// precondition: this stack is not full
// adds item to this stack
{
Node *newNode = new Node;
newNode->data = item;
newNode->next = topItem;
topItem = newNode;
} // end push
void StackLS::pop(void)
// removes top element from this stack if exist
// remains empty otherwise
{
if (topItem != 0)
{
Node *temp = topItem;
topItem = topItem->next;
delete temp;
}
} // end pop
void StackLS::makeEmpty(void)
// makes this stack empty
{
while (topItem != 0)
{
Node *temp = topItem;
topItem = topItem->next;
delete temp;
}
} // end makeEmpty
// destructor
StackLS::~StackLS(void)
{
//while (!isEmpty())
// pop();
while (topItem != 0)
{
Node *temp = topItem;
topItem = topItem->next;
delete temp;
}
} // end destructor
Here is the main.cpp that I have so far.
main.cpp
#include <iostream>
#include <string>
#include "StackLS.h"
using namespace std;
do {
int main()
{
char answer;
char n;
StackLS stack;
cout << " ********** MENU ********** " << endl;
cout << " 1. Basic Brackets () " << endl;
cout << " 2. Standard Brackets ()[]{} " << endl;
cout << " 3. User-Defined brackets " << endl;
cout << " Please enter your choice: " << endl;
switch (choice){
case 1:
cout << "Current Setting: () " << endl;
cout << "Enter your expression followed by a ; : " << endl;
do {
cin >> answer;
while (answer != ;)
}
} // end main
}
while (choice != 'n' || 'N')
Again I am wondering how I would use the stack I have shown you in this program (main.cpp). I am a little confused on why I would use stack and why. Any help is appreciated. Thanks. The main.cpp may not be right but again I am learning and that is why I am here to learn more. Thanks
When you see an opening brace, you push it onto the stack. When you see a closing brace, you make sure it is the counterpart of the brace on top of the stack, then pop it off. When your input is done, you make sure the stack is empty.

Segfault in recursive function

I'm getting a segfault when I run this code and I'm not sure why. Commenting out a particular line (marked below) removes the segfault, which led me to believe that the recursive use of the iterator "i" may have been causing trouble, but even after changing it to a pointer I get a segfault.
void executeCommands(string inputstream, linklist<linklist<transform> > trsMetastack)
{
int * i=new int;
(*i) = 0;
while((*i)<inputstream.length())
{
string command = getCommand((*i),inputstream);
string cmd = getArguments(command,0);
//cout << getArguments(command,0) << " " << endl;
if (cmd=="translate")
{
transform trs;
trs.type=1;
trs.arguments[0]=getValue(getArguments(command,2));
trs.arguments[1]=getValue(getArguments(command,3));
((trsMetastack.top)->value).push(trs);
executeCommands(getArguments(command,1),trsMetastack);
}
if (cmd=="group")
{
//make a NEW TRANSFORMS STACK, set CURRENT stack to that one
linklist<transform> transformStack;
trsMetastack.push(transformStack);
//cout << "|" << getAllArguments(command) << "|" << endl;
executeCommands(getAllArguments(command),trsMetastack); // COMMENTING THIS LINE OUT removes the segfault
}
if (cmd=="line")
{ //POP transforms off of the whole stack/metastack conglomeration and apply them.
while ((trsMetastack.isEmpty())==0)
{
while ((((trsMetastack.top)->value).isEmpty())==0) //this pops a single _stack_ in the metastack
{ transform tBA = ((trsMetastack.top)->value).pop();
cout << tBA.type << tBA.arguments[0] << tBA.arguments[1];
}
trsMetastack.pop();
}
}
"Metastack" is a linked list of linked lists that I have to send to the function during recursion, declared as such:
linklist<transform> transformStack;
linklist<linklist<transform> > trsMetastack;
trsMetastack.push(transformStack);
executeCommands(stdinstring,trsMetastack);
The "Getallarguments" function is just meant to extract a majority of a string given it, like so:
string getAllArguments(string expr) // Gets the whole string of arguments
{
expr = expr.replace(0,1," ");
int space = expr.find_first_of(" ",1);
return expr.substr(space+1,expr.length()-space-1);
}
And here is the linked list class definition.
template <class dataclass>
struct linkm {
dataclass value; //transform object, point object, string... you name it
linkm *next;
};
template <class dataclass>
class linklist
{
public:
linklist()
{top = NULL;}
~linklist()
{}
void push(dataclass num)
{
cout << "pushed";
linkm<dataclass> *temp = new linkm<dataclass>;
temp->value = num;
temp->next = top;
top = temp;
}
dataclass pop()
{
cout << "pop"<< endl;
//if (top == NULL) {return dataclass obj;}
linkm<dataclass> * temp;
temp = top;
dataclass value;
value = temp->value;
top = temp->next;
delete temp;
return value;
}
bool isEmpty()
{
if (top == NULL)
return 1;
return 0;
}
// private:
linkm<dataclass> *top;
};
Thanks for taking the time to read this. I know the problem is vague but I just spent the last hour trying to debug this with gdb, I honestly dunno what it could be.
It could be anything, but my wild guess is, ironically: stack overflow.
You might want to try passing your data structures around as references, e.g.:
void executeCommands(string &inputstream, linklist<linklist<transform> > &trsMetastack)
But as Vlad has pointed out, you might want to get familiar with gdb.