Unexpected answer for a simple stack problem in C++ - c++

class Solution {
public:
bool isValid(string s) {
map<char , char> m;
m[')'] = '(';
m['}'] = '{';
m[']'] = '[';
stack<char> st;
if(s[0] != '(' || s[0] != '{' || s[0] != '[')
return "false";
for(int i = 0; i<s.length(); i++)
{
if(s[i] == '(' || s[i]== '{' || s[i]== '[')
{
st.push(s[i]);
}
else if(st.top() == m[s[i]])
{
st.pop();
}
else if(st.top() != m[s[i]])
{
return "false";
}
}
if(st.empty())
return "true";
else
return "false";
}
};
The code fails for a basic example such as "(]". I don't understand how this is possible.
( first goes in the stack
( is not the map for ]
So it should return "false". But it returns true.

Regarding your expression:
(s[0] != '(' || s[0] != '{' || s[0] != '[')
For a start, unless s[0] is some weird quantum variable that can be three things at once, that expression will never be false. Think about some possibilities:
Character != '(' != '{' != '[' || all
--------- ------ ------ ------ ------
( false true true true
{ true false true true
[ true true false true
x true true true true
As you can see, every character will have that expression evaluating as true. You probably should be using && rather than ||.
In addition, you return a C-style string from your function which, being a non-zero pointer, will translate to true in a boolean context, as evidenced by:
#include <iostream>
bool returnT() { return "true"; }
bool returnF() { return "false"; }
int main() {
std::cout << returnT() << '\n';
std::cout << returnF() << '\n';
}
which outputs:
1
1
So I would be more inclined to start with something like this:
class Solution {
public:
bool isValid(string s) {
stack<char> st;
map<char, char> m;
m[')'] = '('; m['}'] = '{'; m[']'] = '[';
if (s[0] != '(' && s[0] != '{' && s[0] != '[') {
return false;
}
for (int i = 0; i < s.length(); ++i) {
if (s[i] == '(' || s[i]== '{' || s[i]== '[') {
st.push(s[i]);
} else if (st.top() == m[s[i]]) {
st.pop();
} else if (st.top() != m[s[i]]) {
return false;
}
}
return st.empty();
}
};
But do watch out for one thing. If your valid input characters are limited to the six brackets, you should be okay.
But if you want to allow for other characters that don't affect the stack, such as with:
[14^{6+(2x3)}]
then your code will not work because the first 1 character will be considered a mismatch. To handle that, you'll need to modify it to take them into account.
For example:
for (int i = 0; i < s.length(); ++i) {
if (s[i] == '(' || s[i]== '{' || s[i]== '[') {
// Handle open brackets: store.
st.push(s[i]);
} else if (s[i] == ')' || s[i]== '}' || s[i]== ']') {
// Handle close brackets: check.
if (st.top() == m[s[i]]) {
st.pop();
} else {
return false;
}
}
// Anything else is just a "noise" character, ignore.
}

Apparently, a ')' must be close to '(' in ascii code.
class Solution {
public:
bool isValid(string s) {
stack<char> st; st.push('\0');
for (auto c : s) {
if (isalpha(c)) continue;
else if (c - st.top() <= 3 && c - st.top() > 0)
st.pop();
else
st.push(c);
}
return st.size() == 1;
}
};
int main() {
Solution solu;
cout << solu.isValid("[](){}") << endl;
cout << solu.isValid(")(") << endl;
}

Related

my c++ postfix converter using stack library

I'm second year in CS
I'm trying to create infix to postfix converter
with this steps:
1.if the char is digit print
2- if it is '(' then add it to the stack
3-if it is ')' then pop to the output until it reaches '('
4- if it is operator the pop from the stack until it can be pushed
into the stack depending on the priority of operators
5- show the
final postfix equation
the problem is I need a loop to scan all the equation characters but I didn't know how to do it
below is my C++ code
#include <iostream>
#include <stack>
#include <cstdio>
using namespace std;
void scan(char);
int priority(char);
void st(char);
void move(char);
char expr;
int main() {
cout << "enter an formula: ";
cin >> expr;
scan(expr);
return 0;
}
void scan(char exp) {
if (isdigit(exp)) {
expr = putchar(exp);
move(exp);
}
else {
st(exp);
move(exp);
}
}
void move(char exp) {
if (expr == exp)
expr = getchar();
}
int priority(char exp) {
if (exp == '(')
return 1;
else if (exp == ')')
return 2;
else if (exp == '%' || exp == '/' || exp == '*')
return 3;
else if (exp == '+' || exp == '-')
return 4;
return 0;
}
void st(char op) {
std::stack<char> stack1;
if (priority(op) == 1) {
stack1.push(op);
}
else if (priority(op) == 2) {
while (stack1.top() != '(') {
putchar(stack1.top());
}
stack1.top();
}
else if (priority(op) == 3) {
if (stack1.empty()) { stack1.push(op); }
if (stack1.top() == '%' || stack1.top() == '/' || stack1.top() == '*')
{
putchar(stack1.top());
}
if (stack1.top() == '+' || stack1.top() == '-') { stack1.push(op); }
}
else if (priority(op) == 4) {
if (stack1.empty()) { stack1.push(op); }
if (stack1.top() == '%' || stack1.top() == '/' || stack1.top() == '*')
{
putchar(stack1.top());
}
if (stack1.top() == '+' || stack1.top() == '-') { putchar(stack1.top()); }
}
}
So I think the mistake is here
char expr;
In C++ char is a type for a single character. It you want a string of characters use the type std::string (and also #include <string>)
string expr;
Then loop through the equation like this
for (char ch : expr)
scan(ch);

C++ Bug fixing: Hawaiian Pronunciation Program

I am writing a C++ program that will show you how to pronounce a Hawaiian word.
Rules:
p, k, h, l, m, n (Pronounced like the english versions.)
w -start of word (Either pronounced as a w or a v sound. We shall pronounce it as a w sound.)
w -after the letter ‘a’ (Either pronounced as a w or a v sound. We shall pronounce it as a w sound.)
w -after ‘i’ or ‘e’ (Pronounced as a v sound.)
w -after ‘u’ or o (Pronounced as a w sound.)
My progress: My program works, but there's a couple of bugs.
When I type "iwa", the pronunciation must be "ee-vah" but I'm
getting "ee-wah".
My code is not ignoring whitespaces. So when I type "e komo mai", I want "eh koh-moh meye" but instead, I get "e komo mai is pronounced eh-eh-koh-moh-oh-meye".
Here is my code:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
string convertToHawaiian(string input);
bool vowelGroup(char first, char next, string& replacement);
bool consonantGroup(char prevchar, char currchar, string& replacement);
bool singleVowel(char current, string& replacement);
int main() {
// Declare my variables
string userInput;
string replacement;
//cout << "Enter a hawaiian word to pronounce ==>";
getline(cin,userInput);
// For loop that will call my Consonant function
// Call my Hawaiian function and put it
// into pronunciation
replacement = convertToHawaiian(userInput);
// if My initial input has a capital, the replacement
// will keep the capital letter at the beginning
if (isupper(userInput.at(0))) {
replacement.at(0) = toupper(replacement.at(0));
}
// Get rid of the '-' character at the end of the string
if (replacement.at(replacement.size() - 1) == '-') {
replacement.pop_back();
}
cout << userInput << " is pronounced " << replacement << endl;
return 0;
}
// My main function that will convert my input
// into the hawaiian pronunciation
string convertToHawaiian(string input) {
char nextChar;
string replacement = "";
string result = "";
// Iterate through my string to check for vowels,
// vowelgroups and consonants.
for (unsigned int i = 0; i < input.size(); i++) {
char character = input.at(i);
character = tolower(character);
if (i != input.size() - 1) {
nextChar = input.at(i + 1);
nextChar = tolower(nextChar);
}
if ((i != input.size() - 1) && (vowelGroup(character, nextChar, replacement))) {
i++;
result = result + replacement;
}
else if (singleVowel(character, replacement)) {
result = result + replacement;
}
else {
consonantGroup(character, nextChar, replacement);
result = result + replacement;
}
}
return result;
}
bool vowelGroup (char first, char nextChar, string& result) {
bool isVowel = true;
if (first == 'a') {
nextChar = tolower(nextChar);
if ((nextChar == 'i') || (nextChar == 'e')) {
result = "eye-";
}
else if ((nextChar == 'o') || (nextChar == 'u')) {
result = "ow-";
}
else {
return false;
}
}
else if (first == 'e') {
nextChar = tolower(nextChar);
if (nextChar == 'i') {
result = "ay-";
}
else if (nextChar == 'u') {
result = "eh-oo-";
}
else {
return false;
}
}
else if (first == 'i') {
nextChar = tolower(nextChar);
if (nextChar == 'u') {
result = "ew-";
}
else {
return false;
}
}
else if (first == 'o') {
nextChar = tolower(nextChar);
if (nextChar == 'i') {
result = "oy-";
}
else if (nextChar == 'u') {
result = "ow-";
}
else {
return false;
}
}
else if (first == 'u') {
nextChar = tolower(nextChar);
if (nextChar == 'i') {
result = "ooey-";
}
else {
return false;
}
}
else {
isVowel = false;
return isVowel;
}
return isVowel;
}
// Check to verify consonants
bool consonantGroup(char character, char nextChar, string& replacement) {
bool isConson = true;
if ((character == 'p') || (character == 'k') || (character == 'h') || (character == 'l') || (character == 'm') || (character == 'n')){
replacement = character;
return isConson;
}
if ((character == 'w') && (nextChar == 'a')) {
replacement = 'w';
return isConson;
}
else if (((character == 'u') || (character == 'o')) && (nextChar == 'w')) {
replacement = 'w';
cout << "Not replacing w" << endl;
return isConson;
}
else if (((character == 'i') || (character == 'e')) && (nextChar == 'w')) {
replacement = 'v';
return isConson;
}
else {
isConson = false;
return isConson;
}
}
bool singleVowel(char current, string& result) {
bool isVowel = true;
if (current == 'a') {
result = "ah-";
return isVowel;
}
else if (current == 'e') {
result = "eh-";
return isVowel;
}
else if (current == 'i') {
result = "ee-";
return isVowel;
}
else if (current == 'o') {
result = "oh-";
return isVowel;
}
else if (current == 'u') {
result = "oo-";
return isVowel;
}
else {
isVowel = false;
return isVowel;
}
}
One of the more common sources of bugs is shared mutable state.
In your case, it is state shared between loop iterations.
The whitespace case is handled here:
else {
consonantGroup(character, nextChar, replacement);
result = result + replacement;
}
and in that case, replacement will be string "spilled over" from the previous iteration.
The remedy is very simple: declare replacement inside the loop instead.
You can solve the "iwa" problem if you stare at these lines until you spot the bug:
if ((character == 'w') && (nextChar == 'a')) {
replacement = 'w';

Conversion of infix to postfix: stack is not recognized error

I am a beginner using the stack so I been trying to do different exercises on it. I'm trying to convert infix->postfix. The xcode debugger says "Use of class template 'stack'requires template arguments'. Here is my code.
#include<iostream>
#include<stack>
#include<string>
using namespace std;
bool IsOperand(char ch)
{
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
return true;
}
return false;
}
bool IsOperator(char C)
{
if (C == '+' || C == '-' || C == '*' || C == '/' || C == '^') {
return true;
}
return false;
}
bool IsLeftParenthesis(char ch)
{
if (ch == '(') {
return true;
}
return false;
}
bool IsRightParenthesis(char ch)
{
if (ch == ')') {
return true;
}
return false;
}
bool Flag(char ch)
{
if (!IsOperand(ch) || !IsOperator(ch) || !IsLeftParenthesis(ch) || !IsRightParenthesis(ch)) {
return false;
}
return true;
}
int IsRightAssociative(char op)
{
if (op == '^') {
return true;
}
return false;
}
int GetOperatorWeight(char op)
{
int weight = -1;
switch (op) {
case '+':
case '-':
weight = 1;
break;
case '*':
case '/':
weight = 2;
break;
case '^':
weight = 3;
break;
}
return weight;
}
bool HasHigherPrecedence(char op1, char op2)
{
int op1Weight = GetOperatorWeight(op1);
int op2Weight = GetOperatorWeight(op2);
// If operators have equal precedence, return true if they are left associative.
// BUT REMEMBER...return false, if right associative.
// if operator is left-associative, left one should be given priority.
if (op1Weight == op2Weight) {
if (IsRightAssociative(op1)) {
return false;
}
else {
return true;
}
}
return op1Weight > op2Weight ? true : false;
}
string InfixToPostfix(string expression)
{
stack S;
string postfix = "";
for (auto& elem : expression) {
if (Flag(elem)) {
continue;
}
// If character is operator, pop two elements from stack, perform operation and push the result back.
else if (IsOperator(elem)) {
while (!S.empty() && S.top() != '(' && HasHigherPrecedence(S.top(), elem)) {
postfix += S.top();
S.pop();
}
S.push(elem);
}
else if (IsOperand(elem)) {
postfix += elem;
}
else if (elem == '(') {
S.push(elem);
}
else if (elem == ')') {
while (!S.empty() && S.top() != '(') {
postfix += S.top();
S.pop();
}
S.pop();
}
}
while (!S.empty()) {
postfix += S.top();
S.pop();
}
return postfix;
}
int main()
{
// std::string expression = "54/(5^2)+(6^2^3)";
std::string expression = "A+(BC-(D/E^F)G)H";
std::string postfix = InfixToPostfix(expression);
std::cout << "Output = " << postfix << "\n";
}
Here specificially where the error is happening.
string InfixToPostfix(string expression)
{
stack S;
It says
Stack S -> Use of class template 'stack'requires template arguments'
Stack is a container, you need to specify the type of the container like:
stack <int> S;
or in you case it is stack of char:
stack <char> S;

Asking about the parenthesis matching in c++

I'm currently working on my first datastructure homework
The topic is "parenthesis matching"
The answer in my mind is simple,
just push the opening parenthesis to the stack , and when you meet the closing parenthesis pop it out.
After finishing my code , I submit it to our school's online judgement system
Only get 9 corrects out of 10 questions.
Here's my c++ code
Is there any situation that I missed in this code?? Thank you all!
/Question's here/
The question is that input a integer N < 1000 which means the testcases
and following N strings length < 1000 should be tested if it's a valid string
If yes , output Case N(from 1~N):Yes
No , output Case N(from 1~N):No
string may contain newline character
#Test cases
Input
2
[][]<>()[{}]
<{>}
Output
Case 1: Yes
Case 2: No
#include <iostream>
#include <string>
using namespace std;
class PARENTHE
{
public:
PARENTHE(int slength);
~PARENTHE();
int StackSize() const;
bool StackEmpty() const;
char top() const;
void Push(const char);
void Pop();
private:
char *str;
int slength;
int stop;
};
PARENTHE::PARENTHE(int slength)
{
str = new char [slength];
stop = -1;
}
PARENTHE::~PARENTHE()
{ delete [] str; }
inline int PARENTHE::StackSize() const
{ return stop+1; }
inline bool PARENTHE::StackEmpty() const
{
return (stop == -1);
}
inline char PARENTHE::top() const
{ return str[stop]; }
void PARENTHE::Push(const char c)
{
str[++stop] = c;
}
void PARENTHE::Pop()
{
stop--;
}
int main()
{
int t;
while( cin>>t )
{
int i = 0;
while( i < t )
{
string temp;
cin>>temp;
if(temp == "\n")
{
cout<<"Case "<<++i<<": "<<"Yes"<<endl;
break;
}
PARENTHE S( 1001 );
bool check = false;
for( int it = 0; it < temp.size() ; ++it )
{
if( temp[it] == '{' || temp[it] == '[' || temp[it] == '(' || temp[it] == '<' )
S.Push(temp[it]);
else if ( temp[it] == '}' || temp[it] == ']' || temp[it] == '>' || temp[it] == ')' )
{
if(!S.StackEmpty())
{
if(( S.top() == '{' && temp[it] == '}' ) || ( S.top() == '(' && temp[it] == ')' ) || ( S.top() == '[' && temp[it] == ']' ) || ( S.top() == '<' && temp[it] == '>' ) )
{
S.Pop();
}
else { break; }
}
else { break; }
}
if ( it == (temp.size()-1) && (!S.StackSize()))
{
check = true;
}
}
if(check)
cout<<"Case "<<++i<<": "<<"Yes"<<endl;
else
cout<<"Case "<<++i<<": "<<"No"<<endl;
}
}
return 0;
}
I would advice You to check the reverse polish notation, it'll handle all Your problems.

C++ program for checking a string for balanced ()s, {}s and []s

So here's my problem:
I'm supposed to write a c++ program that checks a string to be balanced. So far I have the code working to make sure that it has the same number of ('s and )'s (the same with ['s and {'s). The problem is that this works for almost everything, but it doesn't work for strings where the {'s, ('s and ['s all get mixed up.
For example: "{ { [ ( ) ] } ( ) }" comes back as balanced (true) as it should. However, "{ ( [ ] } )" comes back true, but it shouldn't.
What are some ideas in the logic and/or code that would check for when they're out of order?
Thanks for any help!
In case it helps, my code follows:
bool ExpressionManager::isBalanced(string expression)
{
//remove whitespace
string edited;
for(int i = 0; i < expression.length(); i++)
{
if(expression[i] == ' ')
{
continue;
}
else
{
edited += expression[i];
}
}
expression = edited;
//set up brckets
string brackets;
for(int i = 0; i < expression.length(); i++)
{
if (expression.at(i)=='(')
{
brackets += expression.at(i);
}
if (expression.at(i)=='[')
{
brackets += expression.at(i);
}
if (expression.at(i)=='{')
{
brackets += expression.at(i);
}
if (expression.at(i)=='}')
{
brackets += expression.at(i);
}
if (expression.at(i)==']')
{
brackets += expression.at(i);
}
if (expression.at(i)==')')
{
brackets += expression.at(i);
}
}
int parenbal = 0;
int brackbal = 0;
int mustachebal = 0;
for (int i = 0; i<(brackets.size());i++)
{
if(brackets[i]=='(')
parenbal++;
if(brackets[i]=='[')
brackbal++;
if(brackets[i]=='{')
mustachebal++;
if(brackets[i]==')')
parenbal--;
if(brackets[i]==']')
brackbal--;
if(brackets[i]=='}')
mustachebal--;
}
bool isbalanced = false;
if ((mustachebal==0)&&(brackbal==0)&&(parenbal==0))
{
isbalanced = true;
}
//check for brackets mixed up with other stuff.
return isbalanced;
}
If you employ a Stack to store those tokens, then you are always looking for the closing-counterpart corresponding to the one on the top of the stack or an open-token.
The flow would be
If the token is an open token, push it onto the stack.
If the token is a close token, check if the top of the stack is the corresponding open-token. If it is, then pop the stack as you found them balanced. If it is not, then it's an error.
Seems more like a homework assignment. So I would comment accordingly and allow you to learn a few things.
Always initialize your variables. strings are not initialized in your code.
You do not iterate over the string three time, you can check the string only once.
Use if-else if-else structure instead of if-if-if structure.
Always use brackets braces
Be consistent with your usage, either use at() or [], but dont mix them in code.
//this code may help you check string for balanced brackets with no
//repeated brackets,paranthesis or braces (e.g. [2*{3/(1+2)}].Note: no repeatance of
//brackets
#include <iostream.h>
#include <conio.h>
#include "IntStack.h"
#include <stdio.h>
void main(void)
{
char bracket[20];
gets (bracket);
char arr[6];
int i=0;
while(i<20)
{
switch(bracket[i])
{
case '[':
{
arr[0]=1;
break;
}
case '{':
{
arr[1]=2;
break;
}
case '(':
{
arr[2]=3;
break;
}
case ')':
{
arr[3]=3;
break;
}
case '}':
{
arr[4]=2;
break;
}
case ']':
{
arr[5]=1;
break;
}
default:
cout<<"";
}
i++;
}
if(arr[3]==arr[2])
cout<<"";
else
cout<<" ) or ( is missing "<<endl;
if(arr[1]==arr[4])
cout<<"";
else
cout<<" } or { is missing "<<endl;
if(arr[5]==arr[0])
cout<<"";
else
cout<<" ] or [ is missing"<<endl;
}
void check_brackets (string bituy)
{
int flag = 1
int count[6] = {0, 0, 0, 0, 0, 0};
stack<char> barstack;
for (int i = 0; i < bituy.length(); i++)
{
if (bituy[i] == '{')
count[0]++;
else if (bituy[i] == '}')
count[1]++;
else if (bituy[i] == '(')
count[2]++;
else if (bituy[i] == ')')
count[3]++;
else if (bituy[i] == '[')
count[4]++;
else if (bituy[i] == ']')
count[5]++;
}
for (int i = 0; i < 6; i += 2)
{
if (count[i] != count[i+1])
{
cout << "Wrong Syntax!" << endl;
flag = 0;
break;
}
}
if (flag)
{
for (int i = 0; i < bituy.length(); i++)
{
if (bituy[i] == '{' || bituy[i] == '(' || bituy[i] == '[')
barstack.push(bituy[i]);
else
{
if ((barstack.top() == '{' && bituy[i] == '}') || (barstack.top() == '(' && bituy[i] == ')') || (barstack.top() == '[' && bituy[i] == ']'))
barstack.pop();
else
{
cout << "Wrong Syntax!" << endl;
flag = 0;
break;
}
}
}
}
if (flag)
cout << "No Errors!" << endl;
}
#include<bits/stdc++.h>
using namespace std;
bool isBalance(char n[],int size){
int i,count=0;
//int size=strlen(n);
for(i=0;i<size;i++){
if(n[i]=='{'||n[i]=='['||n[i]=='('){
count ++;
}
else if(n[i]=='}'||n[i]==']'||n[i]==')'){
count --;
}
else return -1;
}
if(count==0)
return true;
else
return false;
}
int main(){
char n[1000];
gets(n);
int size=strlen(n);
bool result=isBalance(n,size);
if(result==true)
cout<<"Balance";
else
cout<<"Not Balance";
return 0;
}
//bracket Chaecker program
void bracket_checker()
{
int i=0;
char d;
char ch;
int count=0;
char *s = new char[21];
fstream out;
out.open("brace.txt",ios::in);
while(out>>d)
{
if(d =='}'|| d ==')' || d == '{' || d =='(')
{
s[i]=d;
i++;
}
}
if (i % 2 != 0)
cout <<"\ninvalid braces";
else if (( s[0] == '}' || s[0]==')' || s[0]==']') || (s[i]=='{' || s[i]=='(' || s[i]=='[' ))
cout <<"\n invalid braces";
else
{
for(int a=0; a<i; a++)
{
if (s[a] == '(' || s[a] == '{' || s[a] =='[' )
push1(s[a]);
if((s[a]=='(' && (s[a+1]=='{' || s[a+1]=='}')) || (s[a]=='[' && (s[a+1]=='{' || s[a+1]=='}')))
break;
else
if (s[a] == ')' || s[a] == '}' )
{
if (head != NULL)
{
ch = pop1();
if( ch == '{' && s[a] == '}' || ch == '(' && s[a] == ')' || ch=='[' && s[a]==']')
cout <<" ";
else
break;
}
else
break;
}
}
if(head==NULL)
cout <<" valid";
else
cout <<"In Valid";
}
}