I am working on my last school assignment for the semester and we are being introduced to stacks for the first time but I am having an issue with my program not analyzing the expression properly. Everything executes but the program always comes out with the result that expression is unbalanced. Any clues to point me in the right direction?
//
// main.cpp
// Balanced Parenthesis
#include "StringStack.h"
#include <iostream>
using namespace std;
int main ()
{
StringStack stack;
char entry;
int parCounter = 0;
cout << "This program will accept a string and determine whether it has balanced parenthesis.\n";
cout << "Please type a sentence to be analyzed\n";
while (cin.get (entry) && entry != '\n')
{
stack.push(entry);
}
if (stack.isEmpty()) {
cout << "The stack is empty./n";
}
else{
stack.pop(entry);
if (entry == ')') {
parCounter++;
}
else if(entry == '('){
parCounter--;
}
}
if (parCounter > 0 || parCounter < 0){
cout << "This expression has UNBALANCED parentheses\n";
}
else
{
cout << "This expression has BALANCED parentheses\n";
}
return 0;
}
// StringStack.h
// Balanced Par
#include <iostream>
using namespace std;
#ifndef StringStack_h
#define StringStack_h
//Define our stack class and its contents
class StringStack
{
private:
char *stackArray;
int stackSize;
char top;
public:
StringStack();
~StringStack() {delete[] stackArray;}
void push(char);
void pop(char &);
bool isBalanced();
bool isEmpty();
};
#endif
//Constructor
StringStack::StringStack()
{
stackArray = new char[stackSize];
top = 0;
}
//Function to determine if stack is empty.
bool StringStack::isEmpty()
{
if (top == 0)
return true;
else
return false;
}
//Function to push letters/puncuation onto the stack
void StringStack::push(char letter)
{
//if (isEmpty())
{
top++;
stackArray[top] = letter;
}
//else
//{
//exit(1);
//}
}
//Function to pop letters/puncuation off the stack
void StringStack::pop(char &letter)
{
if (isEmpty())
{
cout << "The stack is empty.\n";
exit(1);
}
else
{
letter = stackArray[top];
top--;
}
}
You're not initialising or setting the member stackSize anywhere. This makes new char[stackSize] undefined behaviour and anything could happen.
And after you fix that, you're only inspecting the top of the stack. You need a loop around the parCount - controlling if to run until the stack is empty.
Related
I'm new to programming in C++. Also new to implementing stacks. My objective is creating RPN Calculator using template stack. Cant use the built in stack classes.
I have everything so far and now I am stuck, I can't think of how to fix this problem. I am currently getting these errors:
Error C2109 subscript requires array or pointer type
Warning C4244 'return': conversion from 'double' to 'int', possible loss of data
This is my stack class:
#include<stack>
#define STACK_MAX 500
template<class T>
class RPNCalculator
{
private:
//Insanciating stack class
T data[STACK_MAX];
int size;
//stack<T> rpnstack;
public:
RPNCalculator() {
size = 0;
}
~RPNCalculator();
int Top() {
if (size == 0) {
fprintf(stderr, "Error: stack empty\n");
return -1;
}
return data[size - 1];
}
void push(T data); // pushes a new operand onto the stack
// the following operations are to be performed as defined for Reverse Polish Notation
// binary operators:
T value(); // returns the topmost value
void pop(); // returns the topmost value and pops it off the top
double add();
double subtract();
double multiply();
double divide();
// unary operators:
double square(); // squares the current value
double negate(); // negates, i.e. 3 becomes -3
bool isEmpty(); // tests to see if there are elements on the stack
void clear(); // clears out the stack
};
template<class T>
inline bool RPNCalculator<T>::isEmpty()
{
bool status;
if (!top)
status = true;
else
status = false;
return status;
}
template<class T>
void RPNCalculator<T>::clear()
{
}
template<class T>
inline RPNCalculator<T>::~RPNCalculator()
{
}
template<class T>
inline void RPNCalculator<T>::push(T data)
{
if (size < STACK_MAX)
data[size++] = data;
else
fprintf(stderr, "Error: stack full\n");
}
template<class T>
inline T RPNCalculator<T>::value()
{
return T();
}
template<class T>
inline void RPNCalculator<T>::pop()
{
if (size == 0)
fprintf(stderr, "Error: stack empty\n");
else
size--;
}
This is my main class:
#include <iostream>
#include "RPNCalculator.h"
#include <string>
#include <sstream>
using namespace std;
bool isOperator(const string& input);
void performOperation(const string& st, RPNCalculator<double>& rpnstack);
int main() {
cout << "Welcome to the RPN Calculator by AbdulFatai Saliu __D00168401" << endl;
cout << "Enter c to clear \n"
<< "s to square \n"
<< "n to negate \n"
<< "p to pop current value \n"
<< "q to quit \n"
;
RPNCalculator<double> rnpstack;
string input;
while (true) {
//Dispaly prompt
cout << ">> ";
//get user input
cin >> input;
//check for numeric values
double numereric;
if (istringstream(input) >> numereric) {
}
else if (isOperator(input)) {
}
else if (input == "q") {
return 0;
}
else {
cout << "Input Not Valid" << endl;
}
//check for operators
//check for exit
// display invalid value message
}
system("PAUSE");
//return 0;
}
bool isOperator(const string& input) {
string operators[] = { "-","+","*","/"};
for (int i = 0; i < 6; i++) {
if (input == operators[i]) {
return true;
}
}
return false;
}
void performOperation(const string& input, RPNCalculator<double>& rpnstack) {
double firstValue, secondValue, result;
firstValue = rpnstack.Top();
rpnstack.pop();
secondValue = rpnstack.Top();
rpnstack.pop();
if (input == "-") {
result = secondValue - firstValue;
}
else if (input == "+") {
result = secondValue + firstValue;
}
else if (input == "*") {
result = secondValue * firstValue;
}
else if (input == "/") {
result = secondValue / firstValue;
}
cout << result << endl;
rpnstack.push(result);
}
the problem seems to be coming from my push() method in the RPNCalculator template class.
Looks like you have a parameter for the function void push(T data); where the parameter has the same name as the class member (data, your storage). Try changing the parameter name in the function implementation that doesn't yield this conflict. You could also be specific which data you want to use if you really want to use that name.
Try this one instead
template<class T>
inline void RPNCalculator<T>::push(T arg)
{
if (size < STACK_MAX)
data[size++] = arg;
else
fprintf(stderr, "Error: stack full\n");
}
or, if you want to be explicit about which data you are assigning
template<class T>
inline void RPNCalculator<T>::push(T data)
{
if (size < STACK_MAX)
this->data[size++] = data; // this->data is the member, data is the function local variable
else
fprintf(stderr, "Error: stack full\n");
}
This is usually avoided by naming the member variables in a way where there can't be conflicts. One way is to prefix your members with m_, where data would become m_data. Feel free to use any style of code that you want, but I'd suggest avoiding conflicts (and the second approach) when possible.
I need to check if number of letters "a" is equal to number of letters "b" using stack.
So i understand logic of this task, but my code doesn't work.
Logic:
If current letter == to letter in stack (s.pop()) or stack is empty then push into stack
else pop from stack
after end of cycle check size of stack. If it is empty so number of letters is equl, else not
I already have class stack
#include <string>
#include <iostream>
#include <cstdlib> // для system
using namespace std;
class stack {
public:
stack() {
ptr = 0;
}
~stack() {}
bool push(int val) {
if (ptr >= MAXSIZE) return false;
body[ptr++] = val; return true;
}
bool pop(int *val) {
if (ptr == 0) return false;
*val = body[--ptr]; return true;
}
bool empty() {
return ptr == 0;
}
private:
enum { MAXSIZE = 100 };
int body[MAXSIZE];
int ptr; // указатель на последний элемент
};
int main()
{
stack s;
std::string str;
std::cout << "Enter your ab string ";
getline(std::cin, str);
for (int c : str) {
if (c == s.pop(&c) || s.empty()) {
s.push(c);
}
else {
s.pop(&c);
}
}
if (s.empty()) {
cout << "YES\n";
system("pause");
return 0;
}
else {
cout << "NO\n";
system("pause");
}
}
result for abab, aabb, ab 'YES'
for aaabb, aba 'NO'
You need a method to look at current value on top of stack without popping it:
class stack {
...
int top() { // never use on an empty stack
return body[ptr-1];
}
...
};
That way you can write:
for (int c : str) {
// short circuit evaluation ensures that top is never called on an empty stack
if (s.empty() || (c == s.top()) {
s.push(c);
}
else {
s.pop(&c);
}
If you cannot, you must push back the popped value if it should not have been popped:
for (int c : str) {
int d;
if (! s.pop(&d)) { // s was empty
s.push(c);
}
else if (c == d) {
s.push(d); // should not have been popped
s.push(c);
}
}
You can push everytime you see a.
for (int c = 0; c < str.size() ; ++c) {
if (str[c] == 'a') s.push('a');
}
if ((s.size() * 2) == str.size()) cout << "YES\n"; else cout << "NO\n";
stack::size can be implemented this way:
int stack::size() {
return ptr;
}
I am trying to implement a system that would perform something like say the user enters 4 5 +. It would add the 4 and 5 (9) and push 9 into the stack.
For some reason the values in the stack are huge numbers so I believe it has something to do with a pointer or accessing a wrong field but I'm pulling my hair out trying to find the error. Any help on what I'm doing wrong?
#include "stack.h"
int main()
{
stack Test;
bool stop = false;
float runningtotal = 0;
while (stop == false)
{
char input;
cin >> input;
if (input == '+') {
int value1 = Test.top();
Test.pop();
int value2 = Test.top();
Test.pop();
cout << value1+value2 << endl;
Test.push(value1 + value2);
}
cout << Test.top();
std::getchar();
std::getchar();
}
And the implementation of stack
#include "stack.h"
stack::stack()
{
maxsize = MaxSize;
currentsize = 0;
sptr = new StackElement[maxsize];
}
stack::~stack()
{
delete [] sptr;
}
void stack::push(StackElement data)
{
if (currentsize < maxsize)
{
sptr[currentsize] = data;
currentsize++;
} else {
cout << "Stack is full ;-;";
}
}
void stack::pop()
{
if (currentsize == 0) {
cout << "Empty stack? ;-;";
return;
}
currentsize--;
}
StackElement stack::top()
{
if (currentsize == 0) {
cout << "Empty stack u ninja ;-;";
return NULL;
} else {
return (sptr[currentsize]);
}
}
void stack::push(StackElement data)
{
if (currentsize < maxsize)
{
sptr[currentsize] = data;
currentsize++; //<--- incrementing after so nothing in [currentsize] now
} else {
cout << "Stack is full ;-;";
}
}
StackElement stack::top()
{
if (currentsize == 0) {
cout << "Empty stack u ninja ;-;";
return NULL;
} else {
return (sptr[currentsize]);// should use currentsize-1
// latest filled cell
// since its pushing from top
}
}
Be sure to convert those ascii codes(49 ish) from keyboard to integer type explanations.
input - 48 should do it.
#include<iostream>
#include<cstring>
using namespace std;
#define MAX 5
struct node
{
char data;
struct node *next;
};
class stack
{
public:
node *top;
stack() //constructor
{
top=NULL;
}
char Top() //return top element without popping
{
return(top->data);
}
int empty() //check empty
{
if(top==NULL)
return(1);
return(0);
}
void push(char x) //push function
{
node *p;
p=new node;
p->data=x;
p->next=top;
top=p;
}
char pop() //pop function
{
node *p;
char x;
p=top;
top=top->next;
x=p->data;
delete(p);
return(x);
}
int precedence(char x) //check precedence of operators
{
if(x=='(')
return 0;
else if(x=='+'||x=='-')
return 1;
else if(x=='*'||x=='/'||x=='%')
return 2;
return 3;
}
void infix_to_postfix(char infix[],char postfix[]);
};
void infix_to_postfix(char infix[],char postfix[])
{
stack s;
char x,token;
int i,j=0;
for(i=0;infix[i]!='\0';i++)
{
token=infix[i];
if(isalnum(token))
postfix[j++]=token;
else
if(token=='(')
s.push(token);
else
if(token==')')
{
while((x=s.pop())!='(')
postfix[j++]=x;
}
else
{
while(s.precedence(token)<=s.precedence(s.Top())&& !s.empty())
postfix[j++]=s.pop();
s.push(token);
}
}
while(!s.empty())
{
x=s.pop();
postfix[j++]=x;
}
postfix[j++]='\0';
}
int main()
{
char infix[30],postfix[30];
cout<<"\nEnter the infix expression::\n";
cin>>infix;
infix_to_postfix(infix,postfix);
cout<<"/nThe equivalent postfix expression is::"<<postfix;
return 0;
}
The above code is giving segmentation fault with gedit in Ubuntu...whereas when the same code when run with turbo C in Windows with the required changes as follows...runs correctly...
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#define MAX 5
struct node
{
char data;
struct node *next;
};
class stack
{
public:
node *top;
stack() //constructor
{
top=NULL;
}
char Top() //return top element without popping
{
return(top->data);
}
int empty() //check empty
{
if(top==NULL)
return(1);
return(0);
}
void push(char x) //push function
{
node *p;
p=new node;
p->data=x;
p->next=top;
top=p;
}
char pop() //pop function
{
node *p;
char x;
p=top;
top=top->next;
x=p->data;
delete(p);
return(x);
}
int precedence(char x) //check precedence of operators
{
if(x=='(')
return 0;
else if(x=='+'||x=='-')
return 1;
else if(x=='*'||x=='/'||x=='%')
return 2;
return 3;
}
void infix_to_postfix(char infix[],char postfix[]);
};
void infix_to_postfix(char infix[],char postfix[])
{
stack s;
char x,token;
int i,j=0;
for(i=0;infix[i]!='\0';i++)
{
token=infix[i];
if(isalnum(token))
postfix[j++]=token;
else
if(token=='(')
s.push(token);
else
if(token==')')
{
while((x=s.pop())!='(')
postfix[j++]=x;
}
else
{
while(s.precedence(token)<=s.precedence(s.Top())&& !s.empty())
postfix[j++]=s.pop();
s.push(token);
}
}
while(!s.empty())
{
x=s.pop();
postfix[j++]=x;
}
postfix[j++]='\0';
}
int main()
{
char infix[30],postfix[30];
cout<<"\nEnter the infix expression::\n";
cin>>infix;
infix_to_postfix(infix,postfix);
cout<<"\nEquivalent postfix expression is::"<<postfix;
getch();
return 0;
}
Why is the problem arising in Ubuntu???
You never check whether your input stack is empty before directly dereferencing top->data. Specifically, this loop:
while(s.precedence(token)<=s.precedence(s.Top())&& !s.empty())
postfix[j++]=s.pop();
s.push(token);
can, and in your case will, dereference an empty stack because you check the empty state after you've already dereferenced the top pointer via s.Top(). You can avoid the inappropriate dereference by using boolean short-circuiting and the proper evaluation order:
while(!s.empty() && s.precedence(token)<=s.precedence(s.Top()))
postfix[j++]=s.pop();
s.push(token);
Input
A*(B+C/(D-A))
Output
The equivalent postfix expression is::ABCDA-/+*
That said, this is extremely brittle. Unless specifically instructed to do so there is no reason you shouldn't be using a custom stack in the first place, as the standard adapter std::stack<> will remove about 90% of this code, and I strongly suggest taking advantage of that.
Finally, this is flat-out bug. Windows or Ubuntu makes no difference. It invokes undefined behavior. That it didn't crash on Windows means you were lucky (or not, since you assumed it was ok because it didn't crash); not right. And in case you're wondering how I noticed this, I saw it in the code, but confirmed it with Valgrind, which confirmed my suspicion immediately.
Using Standard Library for the Heavy Lifting
This gets considerably simpler when you use classes from the standard library for most of the operations, as you can hopefully see below. I kept your algorithm intact, but just used the std::stack adapter and std::string classes for the guts:
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
static int precedence(char x) //check precedence of operators
{
if(x=='(')
return 0;
else if(x=='+'||x=='-')
return 1;
else if(x=='*'||x=='/'||x=='%')
return 2;
return 3;
}
std::string infix_to_postfix(const std::string& infix)
{
std::stack<char> s;
std::string postfix;
for (auto ch : infix)
{
if (isalnum(ch))
postfix.push_back(ch);
else if (ch == '(')
s.push(ch);
else if(ch == ')')
{
while (!s.empty())
{
ch = s.top();
s.pop();
if (ch == '(')
break;
postfix.push_back(ch);
}
}
else
{
while(!s.empty() && precedence(ch)<=precedence(s.top()))
{
postfix.push_back(s.top());
s.pop();
}
s.push(ch);
}
}
while(!s.empty())
{
postfix.push_back(s.top());
s.pop();
}
return postfix;
}
int main()
{
const char infix[] = "A*(B+C/(D-A)+2*(E-F))";
cout << "\nThe equivalent postfix expression is: " << infix_to_postfix(infix);
return 0;
}
Input
A*(B+C/(D-A)+2*(E-F))
Output
The equivalent postfix expression is: ABCDA-/+2EF-*+*
I've got some questions on how to create and use a circular queue class in C++. The questions are in the code as comments because I am looking for general pointers on how to see if I'm on the right track.
Edit:
Adding the specific questions here for clarity:
Do I need a pointer for both the head and the tail of the queue?
Do I initialize a queue like this or is there a better way?
How do I dequeue and return the correct value?
The code:
#include <iostream>
#include <stdexcept>
using namespace std;
class Queue{
private:
int maxSize;
int *data; // Do I maybe need one for head and one for tail?
int counter; // Used to count the amount of elements in the queue.
public:
Queue();
Queue(int max=100);
~Queue();
void clear();
bool empty() const;
bool full() const;
int dequeue() throw (length_error);
void enqueue(int value) throw (length_error);
int length();
};
Queue :: Queue() // Is this the correct way to initialize the queue?
{
data[100];
counter = 0;
maxSize = 100;
}
void Queue::clear()
{
data = NULL;
}
bool Queue::empty()const
{
if(counter == 0)
return true;
return false;
}
bool Queue::full()const
{
if(counter == 100)
return true;
return false;
}
int Queue::length()
{
return counter;
}
int Queue::dequeue() throw (length_error) // How do I get the correct element and then return it.
{
if(counter >= 0)
{
counter--;
return counter;
}
return counter;
}
void Queue::enqueue(int value) throw(length_error)
{
if(counter < maxSize)
{
data[counter] = value;
counter++;
cout << "Adds the number at the end if there is room for it." << endl;
}
else
;// throw(length_error);
}
int main()
{
Queue minQueue;
minQueue.enqueue(10);
minQueue.enqueue(12);
minQueue.enqueue(14);
minQueue.enqueue(16);
minQueue.enqueue(18);
cout << "Empty: " << minQueue.empty() << endl;
cout << "Full: " << minQueue.full() << endl;
cout << "Length: " << minQueue.length() << endl;
minQueue.dequeue();
minQueue.clear();
system("pause");
}
Your code has some issues.
class Queue{
// ...
public:
// Queue(); // deleted this line, since it collides with the next ctor declation.
// A ctor with one optional argument includes a ctor with no arguments
Queue(int max=100);
~Queue();
}
//...
Queue::Queue(int max) // argument required!
{
data = new int[max]; // this is probably what you want
counter = 0;
maxSize = max;
}
void Queue::clear()
{
delete[] data; // see above, must match the allocation
}
int Queue::dequeue() throw (length_error)
{
if(counter > 0) // !!!! dont't decrease when 0
{
counter--;
return data[counter];
}
else
throw(length_error()); // an exception class length_error must exist!
}
These are a few starting points, fill the remaining gaps by yourself.