I am getting a segmentation fault when trying to convert an infix expression into prefix order. I have a postfix using the same logic that works fine the issue seems to be where i try to read the infix expression in reverse but I am not exactly sure why it is faulting. Any help would greatly appreciated Here is the relevant code:
int ParseTree::prefix(string infix)
{
vector<string> exp;
stringstream ss(infix);
string tok;
while(getline(ss,tok,' '))
{
exp.push_back(tok);
}
vector<string> prefix;
stack<string> s;
for(unsigned int i = exp.size() - 1; i >= 0 ; i--)
{
if(parseTry(exp[i]))
{
prefix.push_back(exp[i]);
}
if(exp[i] == "(")
{
s.push(exp[i]);
}
if(exp[i] == ")")
{
while(!s.empty() && s.top() != "(")
{
prefix.push_back(s.top());
s.pop();
}
s.pop();
}
if(isOperator(exp[i]) == true)
{
while(!s.empty() && priority(s.top()) >= priority(exp[i]))
{
prefix.push_back(s.top());
s.pop();
}
s.push(exp[i]);
}
}
while(!s.empty())
{
prefix.push_back(s.top());
s.pop();
}
for(unsigned int i = 0; i < prefix.size(); i++)
{
cout << prefix[i] << " ";
}
return 0;
}
int ParseTree::priority(const string &s)
{
if(s == "*" || s == "/")
{
return 2;
}
if(s == "+" || s == "-")
{
return 1;
}
else
{
return 0;
}
}
bool ParseTree::parseTry(const string &s)
{
bool number = false;
for(unsigned int i = 0; i < s.size(); i++)
{
if(!isdigit(s[i]))
{
number = false;
}
else
{
number = true;
}
}
return number;
}
bool ParseTree::isOperator(const string &s)
{
return (s == "+" || s == "-" || s == "*" || s == "/");
}
Related
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
using namespace std;
class Stack {
public:
string stack[100][1];
int size;
Stack() { size = 0; }
~Stack() {};
void push(string data) {
stack[size][0] = data;
size += 1;
}
bool empty() {
if (size == 0)
{
return true;
}
else
{
return false;
}
}
string pop() {
size -= 1;
return stack[size][0];
}
string top() {
if (empty())
cout << "Stack is empty";
return stack[size - 1][0];
}
};
int pre(char op)
{
switch (op)
{
case '(': case ')': return 0;
case '+': case '-': return 1;
case '*': case '/': return 2;
}
return -1;
}
vector<string> infix_to_postfix(const vector<string>& expr) {
vector<string> postfix;
string op;
Stack st;
for (int i = 0; i < expr.size(); i++) {
if (expr[i][0] == '+' || expr[i][0] == '-' || expr[i][0] == '*' || expr[i][0] == '/') {
while (!st.empty()) {
op = (st.top()[0]);
if (pre(expr[i][0]) <= pre(op[0]))
postfix.push_back(st.pop());
else break;
}
postfix.push_back(expr[i]);
}
else if (expr[i][0] == '(') {
st.push(expr[i]);
}
else if (expr[i][0] == ')') {
while (!st.empty()) {
op = st.pop();
if (op[0] == '(') break;
else {
postfix.push_back(op);
}
}
}
else {
postfix.push_back(expr[i]);
}
}
return postfix;
}
int main() {
auto expr = infix_to_postfix({ "(", "2", "+", "3", ")", "*", "7" });
for (auto& elem : expr)
{
std::cout << elem << ", ";
}
std::cout << "\n";
return 0;
}
This program is supposed to convert from infix to postfix but it is not producing the correct output. I'm expecting the output to be:
2, 3, +, 7, *,
but the output is
2, +, 3, *, 7,
You have two issues.
When handling an operator, after popping the lower precedence operators you need to push the new operator onto the stack rather than adding it to the result:
if (expr[i][0] == '+' || expr[i][0] == '-' || expr[i][0] == '*' || expr[i][0] == '/') {
while (!st.empty()) {
op = (st.top()[0]);
if (pre(expr[i][0]) <= pre(op[0]))
postfix.push_back(st.pop());
else break;
}
st.push(expr[i]);
}
At the end of the function you need to pop any remaining operators off the stack:
while (!st.empty())
{
postfix.push_back(st.pop());
}
return postfix;
I am trying previous year's codejam question of round 1A
link to question
i have submitted this code(start reading from main method, for ease)-
#include <bits/stdc++.h>
using namespace std;
#define range(t) for (int i = 0; i < t; i++)
#define rangeG(i, t) for (i = 0; i < t; i++)
#define printVec(vec) \
for (auto c : vec) \
{ \
cout << c << endl; \
}
vector<string> separate(string s)
{
vector<string> result;
range(s.size())
{
if (s[i] == '*')
{
string temp = s.substr(0, i + 1);
if (temp.size() > 1)
{
result.push_back(temp);
}
s = s.substr(i, s.size());
i = 0;
}
else if (i == (s.size() - 1))
{
string temp = s.substr(0, i + 1);
result.push_back(temp);
s = s.substr(i, s.size());
}
}
return result;
}
void removeAsterisk(string &s)
{
s.erase(remove(s.begin(), s.end(), '*'), s.end());
}
bool setStart(string s, string &start)
{
bool possible = 1;
removeAsterisk(s);
range(min(s.size(), start.size()))
{
if (s[i] != start[i])
{
possible = 0;
}
}
if (possible)
{
if (s.size() >= start.size())
{
start = s;
}
}
return possible;
}
bool setEnd(string s, string &end)
{
bool possible = 1;
removeAsterisk(s);
range(min(s.size(), end.size()))
{
if (s[s.size() - 1 - i] != end[end.size() - 1 - i])
{
possible = 0;
}
}
if (possible)
{
if (s.size() >= end.size())
{
end = s;
}
}
return possible;
}
void solve()
{
int n;
cin >> n;
vector<string> allS;
bool possible = 1;
string start = "";
string end = "";
string middle = "";
string result = "";
while (n--)
{
string str;
cin >> str;
if (count(str.begin(), str.end(), '*') == 0)
{
result = str;
}
vector<string> temp = separate(str);
for (string s : temp)
{
if (s[0] != '*')
{
possible = setStart(s, start);
}
if (s[s.size() - 1] != '*')
{
possible = setEnd(s, end);
}
if (possible && count(s.begin(), s.end(), '*') == 0)
{
result = s;
break;
}
if (s[0] == '*' && s[s.size() - 1] == '*')
{
removeAsterisk(s);
middle += s;
}
}
}
if (possible)
{
if (result.size() == 0)
{
result = start + middle + end;
}
cout << result << "\n";
}
else
{
cout << "*\n";
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t = 0;
cin >> t;
range(t)
{
cout << "Case #" << i + 1 << ": ";
solve();
}
return 0;
}
it seems correct to me and i have tested many times for many examples, but it is losing in test set-1(exactly one * (asterisk) character and and always the first character of string). Can anyone tell what's wrong?
you can consider code of first ranked here (it has all solutions,check only for "pattern matching" task) for help. I know that the wrong answer is an edge case and if it passes test set 1 then it will pass others.
I have implemented Shunting yard algorithm using stack in c++.
Well it is working quite well on inputs from SPOJ example inputs but when I input:
1
(((a+b) * (c+r)^(t+b)-n)^(c-(d * e))-b)+(c+(e-(d^r)))
I get a runtime error.
Note: I only get a runtime error when I call infixToPostfix() and use the above input and not when I comment it out.
Submission to SPOJ and running on ideone(with input above) results in a runtime error.
I really can't understand this behaviour of my program, so any help is welcomed.
I have tried some random inputs and it seems to work fine on them.
Even though they had spaces around operators.
#include<iostream>
#include<vector>
#include<math.h>
#include<stack>
#include<strings.h>
using namespace std;
void infixToPostfix(string st);
int pr(char s);
int main() {
int t;
scanf("%d",&t);
cin.ignore();
string st; // input string
while(t--)
{
getline(cin,st);
cin.sync();
cout<<st<<endl;
infixToPostfix(st);
}
return 0;
}
int pr(char s) // to check precedence
{
if(s == '^')
{
return 4;
}
else if(s == '*')
{
return 3;
}
else if(s == '/')
{
return 3;
}
else if(s == '+')
{
return 2;
}
else if(s == '-')
{
return 2;
}
else {
return 0;
}
}
void infixToPostfix(string st)
{
stack<char>op; //stack to hold operators and bracket
st += 'n';
int l = st.size();
op.push('0');
string fst; //final string
for(int x = 0;x<l;x++)
{
if(st[x] == '(')
{
op.push(st[x]);
}
else if(st[x] == ')')
{
while(op.top() != '(' && !op.empty())
{
fst +=op.top();
op.pop();
}
op.pop();
}
else if(st[x] == '+' || st[x] == '-' || st[x] == '*' ||st[x] == '/' ||st[x] == '^')
{
if(pr(st[x]) <= pr(op.top()))
{
fst += op.top();
op.pop();
op.push(st[x]);
}
else{
op.push(st[x]);
}
}
else if(st[x] == 'n'){
while(op.size() != 0)
{
if(op.top() != '0')
{fst += op.top();}
op.pop();
}
}
else if((st[x] >= 'a' || st[x] <= 'z' )&& st[x] != ' ')
{
fst += st[x];
}
}
printf("%s\n",fst.c_str());
}
So I am working on some homework for my uni and need to convert a string to a float. For whatever reason g++ is complaining that the 'stof' function doesn't exist. Although I have included the required header. Here is my code, the error is on the line that says
holder = stof(x.substr(0, end_of_num));
#include <iostream>
#include <string>
#include <list>
using namespace std;
float process_func(string x);
bool isPartOfNum(char x);
int main() {
string x;
while (true) {
cout << "input a string" << endl;
getline(cin, x);
cout << process_func(x);
}
return 0;
}
float process_func(string x) {
int end_of_num =0;// used to find last index from num
int negMult = 1; //used to multiply value at end if there was a negative
bool onNum = false; //used to
list <float> numList;
list <char> operList;
if ((x.at(0) < 48 || x.at(0) > 57) && x.at(0) != '-') //check if start of string doesnt have a number or negative symbol
return -1;
if (x.at(0) != '-')
negMult = -1;
float holder;// temp holder for floats
int i = 0;
while (i<x.length()) {
if (isPartOfNum(x.at(i))) {
end_of_num++;
onNum = true;
}
else if (onNum) {
holder = stof(x.substr(0, end_of_num));
numList.push_back(holder); //adds num as float to list
x.erase(0, end_of_num + 1); //+1 removes the space after the number before the operator
end_of_num = 0;
onNum = false;
}
if (x.at(i) == '+' || x.at(i) == '-' || x.at(i) == '*' || x.at(i) == '/') {
operList.push_back(x.at(i));
}
} //at this point both lists should be full of all needed pieces of info
int answer = 0;
int temp;
bool firstOper=true; // used to hold first operation
while (numList.size() >=2) { //requires at least 2 entries for last operation
while (!operList.empty()) {
temp = numList.front();
numList.pop_front();
if (operList.front() == '+') {
if (firstOper) {
answer = temp + numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer += temp;
}
}
else if (operList.front() == '-') {
if (firstOper) {
answer = temp - numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer -= temp;
}
}
else if (operList.front() == '*') {
if (firstOper) {
answer = temp * numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer *= temp;
}
}
else if (operList.front() == '/') {
if (firstOper) {
answer = temp / numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer /= temp;
}
}
operList.pop_front();
}
}
return answer;
}
bool isPartOfNum(char x) {
if ((x >= 48 && x <= 57) || (x == '-' || x == '.'))
return true;
return false;
}
Solved by compiling using c++ 11
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";
}
}