I was trying this parenthesis matching stack code and every time I run this it only gives me that parenthesis are not matching I don't know what is going wrong. Can you guys please help me out in this and tell me how can I improve this further and is this the right way to use stack in c++ because I was studying from a source that is using c language.
#include<iostream>
using namespace std;
struct stack
{
int size;
int top;
char *arr;
};
int isEmpty(struct stack *ptr)
{
if(ptr->top==-1)
{
return 1;
}
return 0;
}
int isFull(struct stack *ptr)
{
if (ptr->top == ptr->size-1)
{
return 1;
}
return 0;
}
void push(struct stack *ptr,char val)
{
if(isFull(ptr))
{
cout<<"stack overflow"<<endl;
}
else
{
ptr->top++;
ptr->arr[ptr->top] = val;
}
}
char pop(struct stack *ptr)
{
if (isEmpty(ptr))
{
cout<<"stack underflow"<<endl;
return -1;
}
else
{
char val = ptr->arr[ptr->top];
ptr->top-1;
return val;
}
}
int parenthesisMatch (char * exp)
{
struct stack * sp = new struct stack;
sp->size = 80;
sp->top = -1;
sp->arr = new char(sp->size);
for(int i=0; exp[i]!='\0'; i++)
{
if (exp[i] == '(')
{
push(sp,'(');
}
else if(exp[i] == ')')
{
if (isEmpty(sp))
{
return 0;
}
pop(sp);
}
}
if (isEmpty(sp))
{
return 1;
}
return 0;
}
int main()
{
char *exp = "((8)(*--$$9))";
if(parenthesisMatch(exp))
{
cout<<"The parenthesis is matching\n";
}
else
{
cout<<"The parenthesis is not matching\n";
}
return 0;
}
Just tried to debug the code and found 2 potential errors:
As correctly pointed out by #Welbog in the comments, to create an array, use sp->arr = new char[sp->size; in the function parenthesisMatch().
In the function pop(), the value of the top is not decremented correctly.
Have a look at the working code:
#include<iostream>
struct stack
{
int size;
int top;
char *arr;
};
int isEmpty(struct stack *ptr)
{
if(ptr->top==-1)
{
return 1;
}
return 0;
}
int isFull(struct stack *ptr)
{
if (ptr->top == ptr->size-1)
{
return 1;
}
return 0;
}
void push(struct stack *ptr,char val)
{
if(isFull(ptr))
{
std::cout<<"stack overflow"<<std::endl;
}
else
{
ptr->top++;
ptr->arr[ptr->top] = val;
}
}
char pop(struct stack *ptr)
{
if (isEmpty(ptr))
{
std::cout<<"stack underflow"<<std::endl;
return -1;
}
else
{
char val = ptr->arr[ptr->top];
ptr->top-=1;
return val;
}
}
int parenthesisMatch (char * exp)
{
struct stack * sp = new struct stack;
sp->size = 80;
sp->top = -1;
sp->arr = new char[sp->size];
for(int i=0; exp[i]!='\0'; i++)
{
if (exp[i] == '(')
{
push(sp,'(');
}
else if(exp[i] == ')')
{
if (isEmpty(sp))
{
return 0;
}
pop(sp);
}
}
if (isEmpty(sp))
{
return 1;
}
return 0;
}
int main()
{
char *exp = "((8)(*--$$9))";
if(parenthesisMatch(exp))
{
std::cout<<"The parenthesis is matching\n";
}
else
{
std::cout<<"The parenthesis is not matching\n";
}
return 0;
}
This is a Stack class based on a dynamic array of struct for Depth First Search (DFS). The program is not able to run whenever it encounters the function, push(), which shows that the array is not successfully initialized in the constructor.
I have tried to look for the error and even changing the dynamic array of struct into parallel arrays but it still does not work. I apologize if the problem seems to be too simple to be solved as I do not have a strong foundation in C++.
#include <iostream>
#include <iomanip>
#ifndef HEADER_H
#define HEADER_H
using namespace std;
struct Value
{
int row; // row number of position
int col; // column number of position
//operator int() const { return row; }
};
class ArrayStack
{
public:
int top;
Value* array;
ArrayStack();
bool isEmpty();
bool isFull();
void push(int r, int c);
void pop();
int poprowvalue(int value);
int popcolvalue(int value);
int peekrow(int pos);
int peekcol(int pos);
int count();
void change(int pos, int value1, int value2);
void display();
void resize();
private:
int size;
};
ArrayStack::ArrayStack()
{
//Initialize all variablies
top = -1;
size = 10;
Value * array = new Value[size];
for (int i = 0; i < size; i++)
{
array[i].row = 0;
array[i].col = 0;
}
}
bool ArrayStack::isEmpty()
{
if (top == -1)
return true;
else
return false;
}
bool ArrayStack::isFull()
{
if (top == size - 1)
return true;
else
return false;
}
void ArrayStack::resize()
{
if (isFull())
size *= 2;
else if (top == size / 4)
size /= 2;
}
void ArrayStack::push(int r, int c)
{
if (isEmpty() == false)
resize();
array[top + 1].row = r;
array[top + 1].col = c;
top++;
}
void ArrayStack::pop()
{
int value;
if (isEmpty())
{
cout << "Stack underflow" << endl;
}
else
{
poprowvalue(array[top].row);
popcolvalue(array[top].col);
array[top].row = 0;
array[top].col = 0;
top--;
}
}
int ArrayStack::poprowvalue(int v)
{
return v;
}
int ArrayStack::popcolvalue(int v)
{
return v;
}
int ArrayStack::peekrow(int pos)
{
if (isEmpty())
cout << "Stack underflow" << endl;
else
return array[pos].row;
}
int ArrayStack::peekcol(int pos)
{
if (isEmpty())
cout << "Stack underflow" << endl;
else
return array[pos].col;
}
int ArrayStack::count()
{
return (top + 1);
}
void ArrayStack::change(int pos, int value1, int value2)
{
if (isEmpty())
cout << "Stack underflow" << endl;
else
{
array[pos].row = value1;
array[pos].col = value2;
}
}
void ArrayStack::display()
{
for (int i = size - 1; i > -1; i--)
{
cout << array[i].row << " " << array[i].col << endl;
}
}
#endif
I expect it to run well but an exception is always thrown on line 80, which is as follows:
Exception thrown at 0x00007FF6A160487C in Assignment1.exe: 0xC0000005: Access violation writing location 0x0000000000000000.
The problem is this line right here:
Value * array = new Value[size];
This declares a new array variable. You are allocating that array instead, and not your member variable array.
The answer is simple, just change it to this instead:
array = new Value[size];
I solved the given problem as shown in the code
But I am getting wrong answer.
I used the Segment tree approach.
node contains max1 (maximum no in given range) and sum(max sum of two no in given range).
Please help.
#include<iostream>
#include<cstdio>
#include<math.h>
using namespace std;
struct node
{
long long int max1;
long long int sum;
};
node constructstutil(int a[],node tree[],int st,int end,int index)
{
if(st==end)
{
tree[index].max1=a[st];
tree[index].sum=a[st];
return tree[index];
}
int mid=(st+end)/2;
node i=constructstutil(a,tree,st,mid,2*index+1);
node j=constructstutil(a,tree,mid+1,end,2*index+2);
int max2=i.max1+j.max1;
if(max2> i.sum&& max2>j.sum)
{
tree[index].max1=max(i.max1,j.max1);
tree[index].sum=max2;
return tree[index];
}
else
{
if(i.sum>j.sum)
{
tree[index].max1=max(i.max1,j.max1);
tree[index].sum= i.sum;
return tree[index];
}
else
{
tree[index].max1=max(i.max1,j.max1);
tree[index].sum=j.sum;
return tree[index];
}
}
}
node* constructst(int a[],int n)
{
int size,k;
k=(int)(ceil(log2(n)));
size=2*(int)pow(2,k)+1;
node* tree=new node[size];
constructstutil(a,tree,0,n-1,0);
return tree;
}
void updatevalueutil(int a[],node tree[],int s,int e,int i,int val,int index)
{
if(i>e||i<s)
return;
if(s==e&& s== i)
{
tree[index].max1=val;
tree[index].sum=val;
return;
}
int mid=(s+e)/2;
updatevalueutil(a,tree,s,mid,i,val,2*index+1);
updatevalueutil(a,tree,mid+1,e,i,val,2*index+2);
int i1=2*index+1;
int i2=2*index+2;
int max2=tree[i1].max1+tree[i2].max1;
if(max2> tree[i1].sum && max2>tree[i2].sum)
{
tree[index].max1=max(tree[i1].max1,tree[i2].max1);
tree[index].sum=max2;
}
else
{
if(tree[i1].sum>tree[i2].sum)
{
tree[index].max1=max(tree[i1].max1,tree[i2].max1);
tree[index].sum= tree[i2].sum;
}
else
{
tree[index].max1=max(tree[i1].max1,tree[i2].max1);
tree[index].sum=tree[i2].sum;
}
}
}
void updatevalue(int a[],int n,node tree[],int i,int val)
{
a[i]=val;
updatevalueutil(a,tree,0,n-1,i,val,0);
}
node queryutil(int a[],node tree[],int qs,int qe,int s,int e,int index)
{
node t;
t.max1=t.sum=0;
if(qs<=s&&qe>=e)
return tree[index];
if(qs>e || qe<s || qs>qe)
return t ;
int mid=(s+e)/2;
node i=queryutil(a,tree,qs,qe,s,mid,2*index+1);
node j=queryutil(a,tree,qs,qe,mid+1,e,2*index+2);
int max2=i.max1+j.max1;
if(max2> i.sum&& max2>j.sum)
{
t.sum=max2;
t.max1=max(i.max1,j.max1);
return t;
}
else
{
if(i.sum>j.sum)
{
t.sum= i.sum;
t.max1=max(i.max1,j.max1);
return t;
}
else
{
t.sum=j.sum;
t.max1=max(i.max1,j.max1);
return t;
}
}
}
long long int query(int a[],int n,node tree[],int qs,int qe)
{
int s=0;
int e=n-1;
node t= queryutil(a,tree,qs,qe,s,e,0);
return t.sum;
}
int main()
{
int n;
scanf("%d",&n);
int a[n];
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
node* tree=constructst(a,n);
int k;
scanf("%d",&k);
while(k--)
{
char ch;
int index,val;
int qs,qe,ans;
cin>>ch;
if(ch=='U')
{
scanf("%d %d",&index,&val);
updatevalue(a,n,tree,index-1,val);
}
else if (ch=='Q')
{
scanf("%d %d",&qs,&qe);
long long int ans=query(a,n,tree,qs-1,qe-1);
printf("%lld\n",ans);
}
}
}
I need to reverse a stack using recursion in C++. I can only use pop, push, and reverseStack, no additional functions such as insertAtBottom which I've found while search stackoverflow and the web.
I've tried:
void Stack::reverseStack(){
if (isEmpty())
return;
else{
int x;
pop(x);
reverseStack();
push(x);
}
}
but this creates a stack exactly the same as the original.
You will need to implement a function to insert an item at the bottom an example is
void Stack::insertAtBottom(int item) {
if(isEmpty())
push(item);
else {
int x;
pop(x);
insertAtBottom(item);
push(x);
}
}
At which point you can implement your reverse as follows
void Stack::reverseStack(){
if (isEmpty())
return;
else{
int x;
pop(x);
reverseStack();
insertAtBottom(x);
}
}
EDIT:
If they need to be in one function, the following is a combination of the two
void Stack::reverseStack(bool reverse=true,int item=0){
if(reverse) {
if (isEmpty())
return;
else{
int x;
pop(x);
reverseStack();
reverseStack(false,x);
}
} else {
if(isEmpty())
push(item);
else {
int x;
pop(x);
reverseStack(false,item);
push(x);
}
}
}
Cheers!
#include <iostream>
#include <stack>
using namespace std;
stack<int> S, R; // S is original stack, R is reversed stack
void reverseStack() {
if(!S.empty()) {
R.push(S.top());
S.pop();
reverseStack();
}
return;
}
int main() {
S.push(1);
S.push(2);
S.push(3);
S.push(4);
S.push(5);
reverseStack();
// Check if R is reversed
while(!R.empty()) {
cout << R.top() << " ";
R.pop();
}
return 0;
}
Hope this helps!
here is a solution to this problem in C language:
#include <stdio.h>
// functions that can be used push(), pop(), and isEmpty()
// the idea is to hold all the values in Function Call Stack until the stack becomes empty.
//When the stack becomes empty, we insert all the held items one by one at the bottom of the stack
// stack-> 1 2 3 4 becomes 4 3 2 1 when we print
#define size 4
int stk[size];
int top = -1;
void insertAtLast(int element);
int isStackFull()
{
if(top == size - 1)
return 1;
return 0;
}
void push(int val)
{
if(isStackFull()==1)
return;
else
//Task 2: Complete the logic
stk[++top] = val;
}
int isStackEmpty()
{
//Task 1: Write logic for isStackEmpty()
if (top==-1)
return 1;
return 0;
}
int pop()
{
if(isStackEmpty()==1)
return -1;
else
//Task 2: Complete the logic
return stk[top--];
}
void reverse(){
if(isStackEmpty()==1){
return;
}
int temp=pop();
reverse();
insertAtLast(temp);
}
void insertAtLast(int element){
if(isStackEmpty()==1){
push(element); //imp
return;
}
int topElements=pop(); //imp
insertAtLast(element); //imp
push(topElements);
}
int main() {
push(4);
push(3);
push(2);
push(1);
for(int i=0;i<size;i++){
printf("%d ", stk[i]);
}
printf("\n");
reverse();
for(int i=0;i<size;i++){
printf("%d ", stk[i]);
}
return 0;
}
I'm having an issue with the last function in my code that destroys the array, I keep getting Double free or corruption which I think means I'm freeing it up twice but I can't figure out how i'm doing that
Main Code
#include "terrible_dynamic_size_array_unsorted.h"
using namespace std;
int main()
{
int_array arraytest;
init(arraytest);
if(arraytest.count==0)
{
cout<<"Empty array created"<<endl;
}
else
{
cout<<"Error in array creation"<<endl;
}
clear(arraytest);
if(arraytest.count==0)
{
cout<<"Array cleared of data"<<endl;
}
else
{
cout<<"Error in clear function"<<endl;
}
for(unsigned int i=0;i<25;i+=2)
{
if(arraytest.count < arraytest.DEFAULT_CAPACITY)
{
add(arraytest,i);
print(arraytest);
}
else
{
add(arraytest,i);
print(arraytest);
}
}
for(unsigned int i=1;i<25;i+=2)
{
if(arraytest.count < arraytest.DEFAULT_CAPACITY)
{
add(arraytest,i);
print(arraytest);
}
else
{
add(arraytest,i);
print(arraytest);
}
}
if(arraytest.capacity == 2*arraytest.DEFAULT_CAPACITY)
{
cout<<"Resize function works properly"<<endl;
}
else
{
cout<<"Resize not working properly"<<endl;
}
if(contains(arraytest,6))
{
cout<<"Number 6 present in Array"<<endl;
}
else
{
cout<<"Number 6 not in Array Contains not working properly"<<endl;
}
if(contains(arraytest,30))
{
cout<<"Number 30 present in Array Contains not working properly"<<endl;
}
else
{
cout<<"Number 30 not in Array"<<endl;
}
if(remove(arraytest,23) && arraytest.count == 24)
{
cout<<"Number 23 removed from Array"<<endl;
}
else
{
cout << arraytest.count << endl;
cout<<"Number 23 not in Array error in remove"<<endl;
}
if(remove(arraytest,24) && arraytest.count == 23)
{
cout<<"Number 24 removed from Array"<<endl;
}
else
{
cout<<"Number 24 not in Array error in remove"<<endl;
}
if(remove(arraytest,0) && arraytest.count == 22)
{
cout<<"Number 0 removed from Array"<<endl;
}
else
{
cout<<"Number 0 not in Array error in remove"<<endl;
}
if(remove(arraytest,35))
{
cout<<"Error in remove function"<<endl;
}
else
{
cout<<"Number not in Array"<<endl;
}
destr(arraytest);
if(*arraytest.data == 0)
{
cout<<"Array destroyed"<<endl;
}
else
{
cout<<"Error in destroy"<<endl;
}
return 0;
}
Function code
#include "terrible_dynamic_size_array_unsorted.h"
using namespace std;
void init(int_array& arr)
{
arr.count = 0; //set count to 0
arr.capacity = arr.DEFAULT_CAPACITY;
arr.data = new int[arr.capacity];
}
void clear(int_array& arr)
{
destr(arr); //destroys array
init(arr); // initializes array
}
void destr(int_array& arr) //function for destroying array
{
delete[] arr.data;
//*arr.data = 0;
arr.count = 0;
}
void print(const int_array& arr) //prints out the array
{
for (unsigned int i = 0; i < arr.count; ++i)
cout << arr.data[i] << " ";
cout << endl;
}
bool contains(const int_array& arr, const int& target) //
{
unsigned int i;
for (i = 0; i < arr.count; ++i)
{
if (arr.data[i] == target) return true;
//else return false;
}
return false;
}
void resize(int_array& arr) //resizes the array --- WORKING
{
arr.capacity *= 2;
int* new_data = new int[arr.capacity];
for (unsigned int i = 0; i < arr.count; ++i)
{
new_data[i] = arr.data[i];
}
arr.data = new_data;
delete [] arr.data;
}
void add(int_array& arr, const int& payload)
{
if ((arr.count == arr.capacity))
resize(arr);
arr.data[++arr.count] = payload;
}
bool remove(int_array& arr, const int& target)
{
unsigned int i = 0;
if (arr.count == 0)
{
return false;
}
while (i <= arr.count && arr.data[i] != target) {i++;}
if (i > arr.count)
{
return false;
}
arr.data[i] = arr.data[arr.count];
arr.count--;
return true;
}
Header file
#include <iostream>
struct int_array {
int* data;
unsigned int count;
unsigned int capacity;
static const unsigned int DEFAULT_CAPACITY = 20;
};
void init(int_array& arr);
void destr(int_array& arr);
void resize(int_array& arr);
void clear(int_array& arr);
void add(int_array& arr, const int& payload);
bool contains(const int_array& arr, const int& target);
bool remove(int_array& arr, const int& target);
void print(const int_array& arr);
The problem lies with the function void destr(int_array& arr)
Thank you.
arr.data = new_data;
delete [] arr.data;
should be
delete[] arr.data;
arr.data = new_data;
Or, the old array will be leaked and arr.data will point to already freed memory - which will then be illegally freed again by destr.