#include<iostream>
#include<stdio.h>
#define MAX 20
using namespace std;
char stk[MAX];
int top=-1;
void push(char c)
{
if(top==MAX-1)
cout<<"Overflow";
else
{
stk[++top]=c;
}
}
char pop()
{
if(top==-1)
{
return '\0';
}
else
return stk[top--];
}
int priority(char ch)
{
if(ch=='(')
return 1;
if(ch=='+'||ch=='-')
return 2;
if(ch=='*'||ch=='/')
return 3;
if(ch=='^')
return 4;
}
int main()
{
char exp[35],*t,x;
cout<<"Enter expression: ";
fgets(exp,35,stdin);
t=exp;
while(*t)
{
if(isalnum(*t))
cout<<*t;
else if(*t=='(')
push(*t);
else if(*t==')')
{
while((x=pop())!='(')
cout<<x;
}
else
{
if(priority(stk[top])>=priority(*t))
cout<<pop();
push(*t);
}
t++;
}
while(top!=-1)
cout<<pop();
return 0;
}
The output for input:
a+b-(c+d/e)
is
ab+cde/+
-
I don't understand why - is on a newline.
I have just started learning c++ and I am trying to implement some programs I did in c using c++. The same code in c works fine. I think there are some holes in my basic c++ knowledge and I would like to fill them up.
std::fgets does not discard the newline in the input stream like getline would. That means exp contains "a+b-(c+d/e)\n" and not "a+b-(c+d/e)". You either need to remove the newline from exp, switch to cin.getline(), or stop your processing loop when it hits the newline.
Try to change fgets to std::cin. And use std::string instead of char*:
#include <iostream>
#include <string>
int main()
{
string exp;
cout << "Enter expression: ";
std::cin >> exp;
auto t = exp.data();
char x;
for(auto &ch: exp)
{
if(isalnum(ch))
cout << ch;
else if(ch == '(')
push(ch);
else if(ch == ')')
{
while((x = pop()) != '(')
cout << x;
}
else
{
if(priority(stk[top]) >= priority(ch))
cout << pop();
push(ch);
}
}
while(top != -1)
cout << pop();
return 0;
}
In addition to the processing of '\n' as mentioned by NathanOliver, your function priority() doesn't return a value when the user entered any other character not checked in the if statements, so the behavior might be undefined.
Related
I want to give the expression in the form of parenthesis through CIN, like: ()). then, through push & pop operation of the stack, I want the program to print me weather the given expression is BALANCED or NOT. The program works perfectly but only one issue has been found & that is when I enter like ()(, so it tells me that this expression is IMBALANCED which is fine but when I enter like () (, so then it tell me that this expression is BALANCED which is actually not balanced.
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
char Stack[10];
int top=-1;
void push(char ch)
{
if(top<10)
{
top++;
Stack[top] = ch;
}
else
cout<<"Stack Overflow";
}
void pop()
{
if(top > -1)
{
top--;
}
else
cout<<"Stack Underflow";
}
int show(){
cout<<"It is imbalanced.";
}
int main(int argc, char** argv)
{
int a=0,b=0;
string exp;
cout << "Write down the parenthesis:" ;
cin >> exp;
bool check = true;
for(int i=0; i<exp.length(); i++)
{
if(exp[i]== '(')
{
push(exp[i]);
}
else if(exp[i]== ')')
{
if(top == -1)
{
check = false;
break;
}
else
{
pop();
}
}
}
for(int i=0; i<exp.length(); i++)
{
if(exp[i]=='('){
++a;
}
else if (exp[i]==')')
{
b++;
}
}
if(a>b){
cout<<"\n\nGiven Combination is IMBALANCED";
return 0;
}
if(check == true)
cout<<"\n\nGiven Combination is BALANCED";
else
cout<<"\n\nGiven Combination is IMBALANCED";
return 0;
}
The main comments boil down to:
Don’t use a stack when no stack is needed.
And if you do use one, don’t limit it to an arbitrary fixed depth.
Handle errors and report malformed expressions.
Make sure you get the right input; std::getline() may be less error-prone than input tokenized using the >> operators. Just skip spaces (or whatever insignificant characters are allowed in the input).
using namespace std; is an antipattern and a bad habit.
The basic idea: Calculate the nesting depth as you iterate over the string. It must be zero, ultimately. It must not drop below zero at any point.
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <string>
#include <string_view>
using std::size_t;
bool correctly_parenthesized(std::string_view expression) {
size_t depth{0};
for (const auto character : expression) {
switch (character) {
case '(': ++depth; break;
case ')': if (depth) { --depth; break; } else { return false; }
case ' ': break;
default: throw std::invalid_argument("invalid character");
}
}
return depth == 0;
}
int main() {
std::cout << "Write down the parentheses: ";
std::string exp;
std::getline(std::cin, exp);
try {
std::cout << (correctly_parenthesized(exp) ? "YES" : "NO") << std::endl;
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
}
I have solved a problem set for a CPSC class where we have to implement a stack to check if an expression is balanced. For example, when a user enters {a}, the program would check if it has been properly closed and return true or false. My program is running accordingly, but only for char values such as. {, ( & and [. When I enter an input of (2(1+2)) it returns false. The algorithm makes sense and works, but I cannot seem to find the issue with my isBalanced function.
I could really use some help
#ifndef BALANCED_H
#define BALANCED_H
#include<string>
class Balanced {
public:
Balanced(std::string);
bool isBalanced();
bool isMatch(char c, char d);
private:
std::string expression;
};
#endif // BALANCED_H
#include "Balanced.h"
#include <string>
#include<iostream>
#include <stack>
Balanced::Balanced(std::string s) : expression(s)
{
}
bool Balanced::isBalanced()
{
std::stack<char> b;
for(unsigned int i=0; i < expression.size(); i++)
{
if(expression[i]=='{'|| expression[i] == '[' || expression[i] == '(')
{
b.push(expression[i]);
continue;
}
if(b.empty() || !isMatch(b.top(), expression[i]))
{
return false;
}
else{
b.pop();
}
}
return b.empty();
}
bool Balanced::isMatch(char c, char d)
{
if(c == '{' && d == '}')
{
return true;
}
else if(c == '[' && d == ']')
{
return true;
}
else if(c == '(' && d == ')')
{
return true;
}
else
{
return false;
}
}
int main()
{
std::string s;
std::string expression;
std::cout<<"Welcome to balance expression program" <<std::endl;
do{
std::cout<<"Enter any key to continue or type 'Help' to display a help menu ";
std::cout<<"You may also type 'Exit' to exit the program: ";
std::cin>>s;
if(s=="Help")
{
displayHelp();
continue;
}
else if(s=="Exit")
{
break;
}
else{
std::cout<<"Enter an expression: ";
std::cin>>expression;
}
Balanced d(expression);
if(d.isBalanced()!=true){
std::cout<<"The expressions is not balanced";
std::cout<<std::endl;
}
else{
std::cout<<"The expression is balanced";
std::cout<<std::endl;
}
}while(s!="Exit");
return 0;
}
void displayHelp()
{
std::cout<<std::endl;
std::cout<<"The purpose of this program is to check ";
std::cout<<"if an expression is balanced ";
std::cout<<"You will enter an expression and it will check to see if there is
closing ";
std::cout<<"brackets. If the expression is balanced, then it will return true if
not ";
std::cout<<"then the program will return false ";
std::cout<<"You can enter as many expression as you like. If you like to exit
the program, ";
std::cout<<"type 'Exit'"<<std::endl;
std::cout<<std::endl;
}
It would seem that your isMatch function will return false if the current character is not an open or close bracket, thus causing the whole thing to return false.
I've attempted to write a code that checks whether or not a string is a palindrome. Here is the code:
#include <iostream>
#include <string>
using namespace std;
bool pal(string str)//This block of code checks if input string is a palindrome
{
bool valid;
int i;
for (i = 0; i < str.length(); i++)
{
if (str[-i] == str[i])
{
valid = true;
}
else
{
valid = false;
}
}
return valid;
}
int main()
{
string s;
cin >> s;
if (!pal(s))
{
cout << "NO" << endl;
}
else
{
cout << "YES" << endl;
}
return 0;
}
Currently I am getting "Debug Assertion Fail" error.
str[-i] == str[i]
is a problem since negative indices are not valid indices in C++.
You need to change the strategy a little bit.
bool pal(string str)
{
int i = 0;
int j = str.length() - 1;
for ( ; i < j; ++i, --j)
{
if (str[i] != str[j])
{
// No need for any more checks.
return false;
}
}
// If we come here, the string is a palindrome.
return true;
}
C++ Provides us with an inbuilt function reverse() which can be used to reverse the Input string and compare it with un reversed string and print the output. The code goes as follows.
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
string str;
cin>> str;
string rev;
rev = str;
reverse(str.begin(), str.end()); // string reverse operation
if(rev == str){
cout<<"YES"<<endl; // Prints "Yes" if string is palindrome
}else{
cout<<"NO"<<endl; // Prints "No" if string is not palindrome
}
return 0;
}
I am trying to get user input and put it into an array of cstrings separated by a space. When I print the array to the screen though I get nothing. I am sure I am doing something stupid, but I have been stuck trying different ways for a while. Any help would be appreciated. Here is the code.
#include <iostream>
#include <cstring>
using namespace std;
void stuff(char command[][25], int length)
{
char ch;
for(int i = 0; i < length; i ++)
{
int b = 0;
cin.get(ch);
while(!isspace(ch))
{
command[i][b++] = ch;
cin.get(ch);
}
command[i][b] = '\0';
cout << endl;
}
}
int main()
{
char cha[10][25];
char ch;
int len = 0;
while(ch != '\n')
{
cin.get(ch);
if(isspace(ch))
{
len++;
}
}
stuff(cha,len);
for(int i = 0; i < len; i++)
{
cout << cha[i] << endl;
}
cout << len << endl;
return 0;
}
a) ch is undefined when you first test it with while (ch != '\n'). Initialize it to zero or something.
b) You don't write any values into cha in the while loop. Perhaps something like:
int pos = 0;
while(ch != '\n') {
cin.get(ch);
if (isspace((unsigned)ch)) {
if (pos > 0) {
++len;
pos = 0;
}
}
else {
cha[len][pos] = ch;
++pos;
}
}
c) You are reading the stream again in stuff(...) but have already consumed what you wanted to get from the stream in main().
d) This code suffers from a number of buffer overrun and stack corruption opportunities. perhaps use a std::vector<std::string> instead. If it runs out of memory it will throw an exception rather than make a mess on the stack.
Perhaps something like this (untested):
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void main()
{
typedef std::vector<std::string> strvec;
strvec cha;
std::string s;
char ch = 0;
while(ch != '\n') {
cin.get(ch);
if (isspace((unsigned)ch)) {
if (!s.empty()) {
cha.push_back(s);
s.clear();
}
}
else {
s.push_back(ch);
}
}
// don't need to call 'stuff' to null terminate.
for (strvec::iterator i = cha.begin(); i != cha.end(); ++i) {
cout << *i << endl;
}
cout << cha.size() << endl;
}
This could be a little more efficient than it is but hopefully it is easy to understand.
You are reading the whole input in the while cycle in the main to read length(number of strings), but you never store it. Later on in stuff cin.get will read nothing. Maybe store the input in cha during the first cycle?
i'am trying to read postfix expression from txt file and evaluate it
the input is 10 5 * ,the output should be 50, but it reads only 10 and 5,
he can't read the operators neither there ascii code , any help?
here's my code
#include <iostream>
#include <iomanip>
#include <fstream>
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
using namespace std;
#define SIZE 40
int stack[SIZE];
int top=-1;
void push(int n)
{
if(top==SIZE-1)
{
printf("Stack is full\n");
return;
}
else
{
top=top+1;
stack[top]=n;
printf("Pushed element is %d\n",n);
system("pause");
}
}
int pop()
{
int n;
if(top==-1)
{
printf("Stack is empty\n");
system("pause");
return 0;
}
else
{
n=stack[top];
top=top-1;
return(n);
}
}
int main()
{
int str[50],ch;
int i=0;
int n,op1,op2;
ifstream inFile;
ch=str[i];
inFile.open("D:\\me.txt");
if (!inFile)
{
printf( "Unable to open file");
system("pause");
exit(1); // terminate with error
}
while (inFile >> ch)
{
if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='%' || ch=='^' )
{
op1=pop();
op2=pop();
if (op1<op2)
{
n=op1;
op1=op2;
op2=n;
}
if(ch=='+')
n=op1+op2;
else if(ch=='-')
n=op1-op2;
else if(ch=='*')
n=op1*op2;
else if(ch=='/')
n=op1/op2;
else if(ch=='%')
n=op1%op2;
else if(ch=='^')
n=op1^op2;
else
{
printf("The operator is not identified\n");
system("pause");
exit(0);
}
printf("n=%d\n",n);
system("pause");
push(n);
}
else
{
n=ch;
push(n);
}
ch=str[++i];
}
inFile.close();
printf("The value of the arithmetic expression is=%d\n",pop());
system("pause");
return 0;
}
The problem is that ch is an int so inFile >> ch will only read nummbers - the '*' character is ignored.
Also, you have a str[] array which is uninitialized that you periodically read out of to assign to ch (then you ignore whatever just got written into ch). You need to get rid of str[] or complete the thought that made you put it there in the first place...