Infix to postfix evaluating unary negative - c++

I'm sure this has been asked a few times but the other questions I looked at didn't really help me much. Alright so here goes: I've got three functions one that converts an infix expression to a postfix, one that's a preprocessor and one that evaluates the postfix expression. What I'm having trouble with is evaluating a unary negative expression. If I put in my entire code it'll be super long so I'm only going to post up the parts that deal with the negative/minus case:
here's my output:
input: -3
after preprocess: 3
postfix = -3
then a segmentation fault when it should output " total = -3 "
#include "postfix.h"
#include "stack.h"
#include <cstdlib>
#include <cmath>
#include <cstdio>
void eval_postfix(char* postfix){
Stack<double> stack;
char fchar[100];
int j=0;
double a, b, convert, total = 0.0;
for(int i=0; postfix[i] != '\0'; i++){
switch(postfix[i]){
case '-':
a = stack.top();
stack.pop();
b = stack.top();
stack.pop();
total = b-a;
stack.push(total);
break;
I'm pretty sure the error is in that part of the function, I've been trying different things but nothing has been working, more times than not I get a segmentation fault or a zero. I originally tried to apply what I did in the infix2postfix expression (which obviously didn't work) But here's the rest of my code for the negative/minus case...
void infix2postfix(char* infix, char* postfix){
Stack<char> stack;
stack.push('\0');
int pc = 0;
bool c;
for(unsigned int i = 0; infix[i] != '\0'; i++){
//use the switch method to define what to do for each of the operators
switch(infix[i]){
case '-':
c = 0;
//unary negative
if(i==0){
postfix[pc++] = infix[i];
c = 1;
}
else if((infix[i-1] == '*' ||
infix[i-1] == '^' ||
infix[i-1] == '*' ||
infix[i-1] == '/' ||
infix[i-1] == '+' ||
infix[i-1] == '-')&&
i>0){
postfix[pc++]= infix[i];
c=1;
}
else{
if(stack.top() == '*' || stack.top() == '/' || stack.top() == '^'){
while(stack.top() != '\0' && stack.top() != '('){
postfix[pc++] = stack.top();
postfix[pc++] = ' ';
stack.pop();
}
}
}
if (c==0)
stack.push('-');
break;
void preprocessor(char* input){
char output[100];
int oc = 0;
for(unsigned int i=0; input[i] != '\0'; i++){
if((input[i] == '-' && (input[i-1] == '*' || input[i-1] == '^' || input[i-1] == '*'
|| input[i-1] == '/' || input[i-1] == '+' || input[i-1] == '-')
&& i>0)){
//output[oc++] = '0';
output[oc++] = input[i];
}
I'm almost certain that whatever error it is I made (or whatever edit I need to do) is probably something really simple that I just can't see (cause that's usually the case with me) but any nudge in the right direction would be highly appreciated!
**Note: the formatting of my code may not be accurate cause I only copied and pasted the parts I felt were relevant.

It seems to me like what is happening is that your code that evaluates the postfix expression, when it sees a minus sign, treats it as a subtraction. In particular, probably you push 3 onto the stack, and then encounter a minus sign: this triggers the code in the first block you posted, which tries to pop two elements off of the stack and subtract them. However there is only one element on the stack, namely the 3.

Related

Trying to make a conditional forloop when reading from a file

I am trying to create a for loop that has a conditional statement which reads until an operation is found, ex. (+,-,/,*), but every time I try I get an error:
Unhandled exception at 0x7936F2F6 (ucrtbased.dll) in CIS310 Project 44.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
while (getline(infile, hex))
{
n = hex.length();//find the length of the line
for (i = 0; hex[i] != '/'||'+'||'-'||'*'; i++,++k) //loop to split the first hexadecimal number
h1 = h1 + hex[i];
for (i++; i < n - 1; i++) //loop to get the second hexadecimal number
h2 = h2 + hex[i];
n1 = convertDecimal(h1); //convert the first hexadecimal number to decimal
n2 = convertDecimal(h2);
Your condition hex[i] != '/'||'+'||'-'||'*' is malformed. C++ requires that you specify both sides of the operator each time, so you will need something more similar to hex[i] != '/' || hex[i] != '+' || ....
You have to check after every ' | | '(OR), like:
hex[i] != '/' || hex[i] != '+' || hex[i] != '-' || hex[i] != '*'
This is a similar code to what you wrote:
while(getline(file,line))
{
string firstPart = "";
unsigned int i;
//We can use the algorithm library to search for them but its ok
for(i=0;(line[i] != '+') || (line[i] != '-') || (line[i] != '*') || (line[i] != '/') || (line[i] != '\0');i++ );
firstPart = line.substr(0,i);
}
now if you tried this, it will cause the same error (or atleast similar to it), if we even try to print every character in the loop
for(/*stuff*/)
cout << line[i];
Then notice this will become an infinite loop, the problem is that you're checking the character line[i] if it wasn't a + or - or * or / all at the same time, fix this by changing the || to &&.
I'll suppose that your file (named testfile.txt) has the content below:
0xAB+0xCD
0x11-0x03
Sample working code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream file("testfile.txt");
///Don't forget to check if file has opened
if(!file.is_open())
{
cout << "File didn\'t open :(";
return 0;
}
string line;
while(getline(file,line))
{
string firstPart = "",secondPart = "";
char operation;
unsigned int i;
//We can use the algorithm library to search for them but its ok
for(i=0;(line[i] != '+') && (line[i] != '-') && (line[i] != '*') && (line[i] != '/') && (line[i] != '\0');i++ );
firstPart = line.substr(0,i);
operation = line[i];
secondPart = line.substr(i+1,firstPart.size());
}
file.close();
return 0;
}

Stack Calculator based on two stacks

I would like to make an algorithm based on two stacks, but my calcucator does not work well for the operator ')'. It should be on output the last of the numbers stack, but happens nothing when i add any ')'. Any suggestions?
We process further tokens until the end of the expression:
if we encounter a number, we put it back on the stack of values
if we encounter an operator, we put it on the operator stack
if we encounter an opening parenthesis, we do nothing
if we encounter a closing bracket, then:
we take off the operator and two values from the stack
we calculate the value of the expression
we put the result on the stack of values
The calculated value of the expression is on the stack
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <vector>
using namespace std;
int main()
{
string c;
stack<int>numbers;
stack<char>operators;
cin >> c;
string expression(c);
for(unsigned int i =0; i <expression.size(); i++)
{
if( expression[i] >= 48 && expression[i] <= 57 )
{
numbers.push(expression[i]);
}
else if(expression[i] == '(')
{
;
}
else if(expression[i] == '+')
{
operators.push(expression[i]);
}
else if(expression[i] == '-')
{
operators.push(expression[i]);
}
else if(expression[i] == '*')
{
operators.push(expression[i]);
}
else if(expression[i] == '/')
{
operators.push(expression[i]);
}
else if(expression[i] == ')' )
{
if(operators.top()== '+')
{
int a,b, score;
a = numbers.top() - '0';
numbers.pop();
b = numbers.top() - '0';
numbers.pop();
score = a+b;
numbers.push(score);
operators.pop();
}
else if(operators.top()== '-')
{
int a,b, score;
a = numbers.top() - '0';
numbers.pop();
b = numbers.top() - '0';
numbers.pop();
score = b-a;
numbers.push(score);
operators.pop();
}
else if(operators.top()== '*')
{
int a,b, score;
a = numbers.top()- '0';
numbers.pop();
b = numbers.top()- '0';
numbers.pop();
score = a*b;
numbers.push(score);
operators.pop();
}
else if(operators.top()== '/')
{
int a,b, score;
a = numbers.top()- '0';
numbers.pop();
b = numbers.top()- '0';
numbers.pop();
score = b/a;
numbers.push(score);
operators.pop();
}
}
}
cout << numbers.top()<<endl;
return 0;
}
The biggest issues with the code are:
This will only work for single digit numbers (you treat each character as a different number)
The fact that numbers is a char stack limits the number to the size of a char. Due to (1) that limit is not really a problem, but when you try to print it at the end the char value will be treated a string encoding. If numbers were a tack of ints instead, it would be converted to the base 10 representation we all know and love when printed.
The order of the operands is wrong (when you unstack them you get the reverse of what you stacked). This is particularly problematic for divisions and subtractions.
Moving forward you may want to have a tokenizer phase that will abstract away some of the details of the text representation to your calculator. Also, be mindful of preserving the order of the operands (eg. change score = x-y to score = y-x).

A way to sort out inputs according to the order they are inputted?

So I am working on a program that takes an infix expression and converts it to a postfix expression. Meaning when I input a+b, the output will be ab+, And i cant figure out a way to print it out correctly because I cannot think of a way to sort the letters, like how can i translate the input a+b-c to ab+c- instead of abc+-? Source code is still in progress.
#include <iostream>
#include <stack>
using namespace std;
int prec(char in)
{
switch(in) {
case '(': return 0;
case '+':
case '-': return 1;
case '*':
case '/': return 2;
default : return 3;
}
}
int main()
{
stack <char> ops;
//stack <char> high-ops;
char next_character ;
while(!cin.eof()) {
cin >> next_character;
if(next_character =='(' )
ops.push('(');
else if(next_character == ')') {
while(!ops.empty() && ops.top() != '(') {
cout << ops.top();
ops.pop();
}
if(!ops.empty())
ops.pop();
else
cout << "Error/n";
}
if((next_character >= 'a' && next_character <= 'z') || (next_character >= 'A' && next_character <= 'Z') || (next_character >= '0' && next_character <= '9'))
if(next_character == '*' || next_character == '/' || next_character == '+' || next_character == '-') {
if(ops.empty())
ops.push(next_character);
if(prec(next_character) > prec(ops.top()))
ops.push(next_character);
if(prec(ops.top()) > prec(next_character)) {
cout << ops.top();
ops.pop();
if( prec(ops.top()) == prec(next_character)){
ops.push(next_character);
cout << ops.top();
ops.pop();
}
}
}
//if(!ops.empty())
//ops.push(next_character);
}
while(!ops.empty()){
cout << ops.top();
ops.pop();
}
}
You need recursive parsing, not a stack based one.
In psuedo code, it would look like this:
func reorder(expression)
if whole_expression_is_wrapped_with_parentheses
return reorder(expression without wrapping parentheses)
if exists_operator(expression)
oi = operator_index = find_operator(expression)
before = expression.substring(0 to oi-1, including)
operator = expression.charAt(oi)
after = expression.substring(oi + 1 to end of string)
return reorder(before) + reorder(after) + oi
return expression
func exists_operator(expression)
Simply check if any operator is in the expression out of parentheses.
func find_operator(expression)
Return the id of the first operator found out of parentheses.
To implement precedence, ignore lower precedence operators until making sure no higher precedence operators are in the expression
The two helper functions should be implemented with a stack-based parentheses counter, to make sure you search only out of any parentheses.

how to calculate polynomial (x^2^2^2^2+x^2^2^2)

I want to calculate (x^2^2^2^2+x^2^2^2) result should be [x^256+x^16]..but i am unable to do this completely..i also have written a code which is working for first half(before '+') but in other half it fails to do it...
#include<iostream>
#include<string>
#include <algorithm>
#include<sstream>
using namespace std;
int main()
{
string a;
cin >> a;
string s1 = "^";
string::size_type foud;
foud = a.find(s1);
int i = foud;
int flag = 0;
i++;
while (foud != std::string::npos)
{
flag = 0;
cout << i <<"I"<< endl;
while (flag != 1 && i < a.length())
{
if (a[i] == '(' || a[i] == '+' || a[i] == '-' || a[i] == ')')
{
flag++;
cout << "terminator" << endl;
}
else if (a[i] == '^')
{
/*int j = (int)(a[i - 1]);
j = j - 48;
int k = (int)(a[i + 1]);
k = k - 48;
i = k + 1;
int power =0;
power = pow(j, k);
;*/
int j = i;
int k = i;
k--;
j++;
string bcknumber;
while (a[k] != '^' && a[k] != '(' && a[k] != '+' && a[k] != '-' && a[k] != ')')
{
bcknumber = bcknumber + a[k];
k--;
}
cout << bcknumber << endl;
reverse(bcknumber.begin(), bcknumber.end());
cout << bcknumber << endl;
int BK;
BK = stoi(bcknumber);
int FD;
string frdnum;
while (a[j] != '^'&&a[j] != '\0' && a[j] != '(' && a[j] != '+' && a[j] != '-' && a[j] != ')')
{
frdnum = frdnum + a[j];
j++;
}
FD = stoi(frdnum);
int resil = pow(BK, FD);
frdnum.clear();
stringstream s;
string res;
s << resil;
res = s.str();
if (i == 15)
{
a.replace(14, 15, res);
}
else
{
a.replace(i - bcknumber.length(), i + frdnum.length(), res);
}
i--;
bcknumber.clear();
}
else
i++;
}
foud = a.find("^", foud + 1);
i = foud;
i++;
}
cout << a << endl;
system("pause");
}
This is not a trivial problem. You want to build an infix calculator (a + b). A prefix calculator (+ a b) or a postfix calculator (a b +) are simpler, since there are no ambiguities at all. An infix calculator can have a lot of them, depending on the degree of freedom you want the user to have.
In the problem you're exposing, one is tempted to say: well, if there is an operator next to the second operand, then I have to accumulate the last result and operate with that and the next operation. However, there are problems like precedence which will not be deal with with that approach.
I would start creating a prefix calculator. It is a lot easier:
calculate():
opr = match operator
op1 = match operand
if op1 is operator:
back
op1 = calculate
op2 = match operand
if op2 is operator:
back
op2 = calculate
return calc(opr, op1, op2)
Once you have mastered that, then there is the possibility to start with an infix calculator.
One thing to do in the last algorithm would be to change it to avoid recursion, for example.
This is a good exercise, enjoy it. Hope this helps.
This smells like homework/assignment so I will not provide code...
As I see it you want just string parser to string replacing the power part. I am assuming You still do not understand the power math or are wrongly writing/interpreting representation of the string. For example:
x^2^2^2^2 =
(((x^2)^2)^2)^2 =
(((x.x)^2)^2)^2 =
((x.x).(x.x))^2)^2 =
((x.x.x.x))^2)^2 =
((x.x.x.x).(x.x.x.x))^2 =
(x.x.x.x.x.x.x.x)^2 =
(x.x.x.x.x.x.x.x).(x.x.x.x.x.x.x.x) =
(x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x) =
x^16
And not yours x^256. You can not add parenteses where you want they must be placed according to order of math operations otherwise the resulting equation will not match the input string !!!. In case you got defined different parse rules for your parser then in standard math then you need to define them in the Question.
Now how to approach this:
read string
I would start with constant hard-coded string instead of typing it all the time while programing/debugin over and over (as many students do ... I saw few times people typing 5x5 matrix on each build :) ... which is insane)
When the program works only then use the cin reading... as you already do
detect which part of the string is power exponent
exponent=1
Search the string for first ^ and remember the start position i0 if not found goto #4.
Now depending on what follows:
If number multiply exponent by it.
If ^ skip it and goto to #2
if neither stop
Of coarse if you should support parentes then it will be much much more complicated and you need to decode the whole thing which is not trivial which you should also mention in the Question.
replace original exponent string with computed string (if computable)
so the computed string will be "^"<<exponent or "^"+exponent depends on what kind of string arithmetics you using ....
output string
with cout or whatever as you already do

how to check char array with nested if statement?

As you might be able to tell im trying to introduce a counter for how many consonants there are in a certain string, but the output is always 50, unless spaces are involved.
int main(){
char input[50];
int total = 0;
cout << "Enter a string of no more than 50 characters\n";
cin.getline(input,50);
for(int n = 0; n<50;n++){
if(input[n]!='a',input[n]!='A',input[n]!='e',input[n]!='E',input[n]!='i',input[n]!='I',input[n]!='o',input[n]!='O',input[n]!='u',input[n]!='U',input[n]!=' ')
total++;}
cout << total << endl;}
According to wikipedia, comma operator is defined as follows
In the C and C++ programming languages, the comma operator
(represented by the token ,) is a binary operator that evaluates its
first operand and discards the result, and then evaluates the second
operand and returns this value (and type).
In your case, you should use logical AND (&&) instead of comma operation.
More efficiently, you may rewrite your code like this
char c = tolower(input[n]);
if (c >= 'a' && c <= 'z' && c != 'a' && c != 'e' && c != 'i' && c != 'o' && c !='u')
total++;
It will include all the cases.
As everyone has clearly explained, you need to use && operator to ensure all conditions are checked.
if(input[n]!='a' && input[n]!='A' && input[n]!='e' && input[n]!='E' && input[n]!='i' && input[n]!='I' && input[n]!='o' && input[n]!='O' && input[n]!='u' && input[n]!='U' && input[n]!=' '){
total++;
}
One recommendation to avoid multiple checks:
Extract the character to a variable converted to lower or upper case.
char c = input[n] | 32;
Regarding the ',' used; this program might provide more insight along with the WIKI shared :
void main(){
int a=-1;
if(++a,a, a++){ // Works like "||"
printf("Yes %d",a);
}else {
printf("NO %d", a);
}
}
Output: NO 1