I'm trying to convert infix to postfix. I don't think my code is wrong but apparently it is because it doesn't work. I don't know what to change to make my code work properly.
(It worked for a bit before and now it doesn't)
I followed this code from geeksforgeeks: https://www.geeksforgeeks.org/stack-set-2-infix-to-postfix/ but I changed some of it because the code from the website was also wrong.
Sorry if my explanation is a bit unclear. Here's my code:
#include <bits/stdc++.h>
using namespace std;
int checks(char c)
{
if (c=='^')
{
return 1;
}
else if (c=='+' || c=='-')
{
return 2;
}
else if (c=='*' || c=='/')
{
return 3;
} else
{
return -1;
}
}
int main()
{
stack <char> stack;
string result, input;
cout<<"Enter your equation: ";
cin>> input;
for (int i=0; i<input.length(); i+=1)
{
if (input[i]=='(')
{
stack.push(input[i]);
} else if (isalnum(input[i]))
{
result+=input[i];
} else if (input[i]==')')
{
while(!stack.empty() && stack.top() != '(')
{
char c = stack.top();
stack.pop();
result += c;
}
if(stack.top() == '(')
{
char c = stack.top();
stack.pop();
}
} else
{
if (checks(stack.top()) >= checks(input[i]))
{
result+=stack.top();
stack.pop();
} else
{
stack.push(input[i]);
}
}
}
while(!stack.empty())
{
if (stack.top()=='(' || stack.top()==')')
{
stack.pop();
} else
{
result+=stack.top();
stack.pop();
}
}
cout<<"Result is: ";
cout<<result<<endl;
return 0;
}
Are your infix expressions using standard mathematical precedence? If so this will change things significantly compared to simple left to right evaluation.
You need to split your program into two phases. In the first phase you will parse the expression and build up the stack. In the second you will iterate over the stack and evaluate the result.
As I said, the parsing will be determined by the precedence. If you are using standard precedence then the usual approach (which you can read in Stroustrup's "The C++ Programming Language") is to use recursive descent. You would then have different precedences for parens, terms, factors, unary operators and literals. Use an enum for these, not magic numbers like 1, 2, 3.
You may skip step to actually create a tree structure , but have to keep in mind that infix notation is representable by tree while Polish notation is representable by stack. In (a+b)*(c+d) the * is topmost node, next level are two + and a, b,c,d. it's a symmetric tree because all operations commutative. But ((a+b)*(c+d))/3 is asymmetric, topmost node / is not commutative. Similar problem arise with -, because it's not commutative either.
E.g. possible option at each step can be (not a strict algorithm, but illustration how one should act, irt requires defense against malformed syntax)
Token is an "id".It's current level of tree node, scan further right
Token is a commutative operation. It's upper level of node. Next token would be a node of same level
Token is a non-commutative operation, / or -. It's upper level of node. Next token relates to node between current one and operation.
* and / have precedence above + and -, so they are nodes of lower level. E.g. a+b*c, First our tree was +: [a,b], then it is +:[a,*:[b,c]].
Token is (. Scan string and count all braces until you find matching ). E.g. each ( increases counter, each ) decreases. You found match if counter is 0. You have syntax error at hand if you get positive or negative while reaching terminal character..
Everything inside of () is a node of lower level. Scan it after finishing all upper levels.
To actually scan string, a state machine running in loop is required, the sign of finishing would be that there will be no tokens left to process. Can be recursive or not.
If you avoid creating tree, you have to go down and up along tokens in string itself, finding topmost node, push it to stack, then right and left nodes (in that order), push to stack, etc. When you pop stack, last-in first-out, operations would appear in proper order.
Paul Floyd is right to remind of that operator precedence can be used to sort order nodes or tokens, albeit doing it in std::stack is not possible because it got only push and pop operations and no reordering is possible, so you have to store that separately or scan and rescan string to push appropriate elements in.
(Note, than when you use some RPN calculator like on of those TI ones the stack of operations acts as a LILO stack, while when convert from syntax tree to RPN, it's LIFO)
Related
struct node
{
char data;
node *left, *right;
};
constructTree(string expression)
{
for(i = 0; i < expression.length(); i++)
{
if(!(isOperator(expression[i]))
{
temp = createNode(expression[i]);
push(temp);
}
else
{
temp = createNode(expression[i]);
node *temp1, *temp2;
temp1 = pop();
temp2 = pop();
temp->left = temp1;
temp->right = temp2;
}
}
}
int main()
{
string expression = "(a+b)-c*(d/e)";
constructTree(expression);
}
I want to construct expression tree from infix expression which I will take as a string from the user. I tried so much now I am feeling tired of it. Some body please help me in making this expression tree from infix expression!
You are trying to write a parser.
There are so many ways to do this, with some ways being especially optimized for infix expressions, and others being more general.
I personally suggest reading about Recursive Descent parsers, as they are a good starting point to learn about parsers since they are relatively simple and intuitive.
A simple recursive descent parser that handles expression with addition, subtraction, multiplication, division and parentheses would look something like this (This is pseudocode!):
node* readExpr() {
return readAddOrSub();
}
node* readAddOrSub() {
leftTree = readMulOrDiv();
token = peekNextToken(); // look at the next token without consuming it
if (token == '+' || token == '-') {
readNextToken(); // skip operator
rightTree = readAddOrSub();
return an addition or subtraction node with leftTree and rightTree as its left and right sub-trees respectively;
} else {
return leftTree;
}
}
node* readMulOrDiv() {
leftTree = readAtom();
token = peekNextToken();
if (token == '*' || token == '/') {
readNextToken(); // skip operator
rightTree = readMulOrDiv();
return a multiplication node with leftTree and rightTree as its left and right sub-trees respectively;
} else {
return leftTree;
}
}
node* readAtom() {
token = readNextToken()
if (token == '(') {
result = readExpr();
read another token and make sure it's ')';
return result;
} else if (token is a number)
return node holding a number;
else if (token is a variable)
return node holding a variable;
else
error();
}
This assumes you have something that breaks up your string apart into tokens (e.g. "5*(a+12)" should be broken into 7 tokens: the number 5, '*', '(', the variable 'a', '+', the number 12, ')').
Operator precedence is captured by the way that functions that parse an opeator of a certain precedence level call the functions that handle the next level of precedence in a hierarchical fashion. More specifically, a function that tries to parse an addition/subtraction node (readAddOrSub) calls the function that parses the next level of precedence (readMulOrDiv) to get its left and right sub-trees.
Note that readAddOrSub (and readMulOrDiv) calls itself to read the right-subtee so that multiple additions can be chained together ("1+2+3"), but beware that this makes the parser inherently right-associative ("1+2+3" will be parsed as "1+(2+3)").
Of course, it's not very hard to make it left-associative, but I'll leave that to you as an exercise!
Some resources that might help:
Wikipedia article about recursive descent
A recursive descent parser that parses C# (written in C#)
A recursive descent expression parser written in C
I need to sum up or multiplie(it depends on which operation i push in array) first two numbers in stack. If I push operation + and my first two numbers are one and two then my stack value where I pushed + must be 3 , but in my result i get some symbol.
#include<iostream>
using namespace std;
#define MAX 10
int sp=-1;
char stack[MAX];
void push(){
if(sp==MAX-1){
cout<<"Error: stack overflow"<<endl;
return;
}
else{
char x;
cout<<"Insert value in stack: ";
cin>>x;
if(x=='*'){
if(sp>=1){
stack[++sp]=stack[1]*stack[0];
return;
}
else {
stack[++sp]=x;
return;
}
}
else if(x=='+'){
if(sp>=1){
stack[++sp]=stack[0]+stack[1];
return;
}
else {
stack[++sp]=x;
return;
}
}
else stack[++sp]=x;
}
}
void pop(){
if(sp==-1){
cout<<"Error: Stack empty";
return;
}
else{
cout<<stack[sp]<<endl;
sp--;
}
}
void top(){
if(sp==-1){
cout<<"Error: Stack empty";
return;
}
else{
cout<<stack[sp]<<endl;
}
}
void isEmpty(){
if(sp==-1){
cout<<"Stack is empty"<<endl;
return;
}
else{
cout<<"Stack is not empty"<<endl;
}
}
int main(){
for(int i=0;i<8;i++){
push();
}
top();
return 0;
}
Original stack:
3 4 3 + 1 2 * *
Stack that I need to get:
3 4 3 7 1 2 12 12
Stack that I get:
3 4 3 \ 1 2 _ _ (let's say something like that)
So you wanted to implement some postfix calculator. Very good that you noticed that a stack is needed.
For calculators you normally parse the input, store some results on a stack and then operate on the stack elements.
In contrast to what timo said, a parse stack can never be implemented with a std::stack because several top stack elements must be matched against the production in the grammar. For that reason a std::vector is the ideal container.
Now to the problem in the program. OP tries to store integer values and operators like "+" and "*" and results of calculations in the same datatype char. That cannot work. char stores characters like '+' or '*' or '1' but not 1. Internally a character is also encoded as a number (for example using ASCII) and a '1' would be equal to 49. And, if you look at results you cannot store '12' (for all the pros. Yes of course I know) in a char. 12 is a number, not a character.
And if you mix these types and do calculations with that then you get wrong results.
The solutions is to use Tokens and implement them as a std::variant. The variant can have a char an an int. Then your parse stack should be a std:::vector of Token.
This the right approach.
Additionally. In all standard recursive descent parsers you do not operate always on elements 0 and 1. You would replace the used values with the newly calculated one.
There is always the same approach
Read next Token and shift it on a stack
Match the top elements of the stack against a production
Reduce. Replace used elements with result
Some example of a different parser: See here.
This is somehow complicated. You may want to read about formal languages and parser.
I have a global unique path table which can be thought of as a directed un-weighted graph. Each node represents either a piece of physical hardware which is being controlled, or a unique location in the system. The table contains the following for each node:
A unique path ID (int)
Type of component (char - 'A' or 'L')
String which contains a comma separated list of path ID's which that node is connected to (char[])
I need to create a function which given a starting and ending node, finds the shortest path between the two nodes. Normally this is a pretty simple problem, but here is the issue I am having. I have a very limited amount of memory/resources, so I cannot use any dynamic memory allocation (ie a queue/linked list). It would also be nice if it wasn't recursive (but it wouldn't be too big of an issue if it was as the table/graph itself if really small. Currently it has 26 nodes, 8 of which will never be hit. At worst case there would be about 40 nodes total).
I started putting something together, but it doesn't always find the shortest path. The pseudo code is below:
bool shortestPath(int start, int end)
if start == end
if pathTable[start].nodeType == 'A'
Turn on part
end if
return true
else
mark the current node
bool val
for each node in connectedNodes
if node is not marked
val = shortestPath(node.PathID, end)
end if
end for
if val == true
if pathTable[start].nodeType == 'A'
turn on part
end if
return true
end if
end if
return false
end function
Anyone have any ideas how to either fix this code, or know something else that I could use to make it work?
----------------- EDIT -----------------
Taking Aasmund's advice, I looked into implementing a Breadth First Search. Below I have some c# code which I quickly threw together using some pseudo code I found online.
pseudo code found online:
Input: A graph G and a root v of G
procedure BFS(G,v):
create a queue Q
enqueue v onto Q
mark v
while Q is not empty:
t ← Q.dequeue()
if t is what we are looking for:
return t
for all edges e in G.adjacentEdges(t) do
u ← G.adjacentVertex(t,e)
if u is not marked:
mark u
enqueue u onto Q
return none
C# code which I wrote using this code:
public static bool newCheckPath(int source, int dest)
{
Queue<PathRecord> Q = new Queue<PathRecord>();
Q.Enqueue(pathTable[source]);
pathTable[source].markVisited();
while (Q.Count != 0)
{
PathRecord t = Q.Dequeue();
if (t.pathID == pathTable[dest].pathID)
{
return true;
}
else
{
string connectedPaths = pathTable[t.pathID].connectedPathID;
for (int x = 0; x < connectedPaths.Length && connectedPaths != "00"; x = x + 3)
{
int nextNode = Convert.ToInt32(connectedPaths.Substring(x, 2));
PathRecord u = pathTable[nextNode];
if (!u.wasVisited())
{
u.markVisited();
Q.Enqueue(u);
}
}
}
}
return false;
}
This code runs just fine, however, it only tells me if a path exists. That doesn't really work for me. Ideally what I would like to do is in the block "if (t.pathID == pathTable[dest].pathID)" I would like to have either a list or a way to see what nodes I had to pass through to get from the source and destination, such that I can process those nodes there, rather than returning a list to process elsewhere. Any ideas on how i could make that change?
The most effective solution, if you're willing to use static memory allocation (or automatic, as I seem to recall that the C++ term is), is to declare a fixed-size int array (of size 41, if you're absolutely certain that the number of nodes will never exceed 40). By using two indices to indicate the start and end of the queue, you can use this array as a ring buffer, which can act as the queue in a breadth-first search.
Alternatively: Since the number of nodes is so small, Bellman-Ford may be fast enough. The algorithm is simple to implement, does not use recursion, and the required extra memory is only a distance (int, or even byte in your case) and a predecessor id (int) per node. The running time is O(VE), alternatively O(V^3), where V is the number of nodes and E is the number of edges.
I need to implement infix to postfix conversion algorithm to compute the expression a+b*c-d/e
I also need to do this using queue (I believe 2 different queue stacks are needed)
I've created my queue class using a DoubleLinkList and now just need to create the algorithm for this problem. I'm pretty lost on how to go about it, though. Any help would be appreciated!
so far(And I know it's very wrong) I have:
string infix = "a+b*c-d/e";
Queue *holder = new Queue();
Queue *newstring = new Queue();
int length = infix.length();
char temp;
char prev;
for(int i=0; i<length; i++)
{
temp = infix[i];
if((temp == '+') || (temp == '-') || (temp == '*') || (temp == '/'))
{
if (holder->isEmpty())
{
holder->queue(temp);
}
if(temp<holder.enqueue())
{
}
}
holder->queue(temp);
}
I assume this is a homework assignment so it is important that you figure out the programming details on your own. The general outline of the algorithm is as follows:
Define a stack
Go through each character in the string
If it is between 0 to 9, append it to output string.
If it is left brace push to stack
If it is operator *+-/ then
If the stack is empty push it to the stack
If the stack is not empty then start a loop:
If the top of the stack has higher precedence
Then pop and append to output string
Else break
Push to the stack
If it is right brace then
While stack not empty and top not equal to left brace
Pop from stack and append to output string
Finally pop out the left brace.
If there is any input in the stack pop and append to the output string.
I think you should create a tree of operators and values.
You can convert from infix to postfix to prefix depending on your traversal order of the tree.
Your instructor may have give you assignments to convert between the three.
Here are some articles:
University of Texas
YouTube video
Wikipedia - Expression trees
Ok, I already have it in postfix notation and I am sending over a string variable that will have the postfix notation as something such as: 5 15 2 *+
Here is my code:
int evaluatePostFix(string postfix_expression){
//Create a new stack
stack<int> theStack;
//Loops while the postfix expression string still contains values
while(postfix_expression.length()>=1){
//Loops on a number an whitespace
while(isdigit(postfix_expression.at(0)) || isspace(postfix_expression.at(0))){
//Holds a number that is above two digits to be added to the stack
string completeNum;
if(isdigit(postfix_expression.at(0))){
//Add the digit so it can become a full number if needed
completeNum+=postfix_expression.at(1);
}
else {
//Holds the integer version of completeNum
int intNum;
//Make completeNum an int
intNum=atoi(completeNum.c_str());
//push the number onto the stack
theStack.push(intNum);
}
//Check to see if it can be shortened
if(postfix_expression.length()>=1){
//Shorten the postfix expression
postfix_expression=postfix_expression.substr(1);
}
}
//An Operator has been found
while(isOperator(postfix_expression.at(0))){
int num1, num2;
char op;
//Grabs from the top of the stack
num1=theStack.top();
//Pops the value from the top of the stack - kinda stupid how it can return the value too
theStack.pop();
//Grabs the value from the top of the stack
num2=theStack.top();
//Pops the value from the top of the stack
theStack.pop();
//Grab the operation
op=postfix_expression.at(0);
//Shorten the postfix_expression
postfix_expression=postfix_expression.substr(1);
//Push result onto the stack
theStack.push(Calculate(num1,num2, op));
}
}
return theStack.top();
}
The error I get is "Deque iterator not deferencable"
Any help that I can get on this error would be much appreciated.
btw I haven't used C++ in a couple of years so I'm a bit rusty.
It would be easier if you told us which line was causing the error by stepping through with a debugger. However, I think I may have spotted the error.
In this block of code
if(isdigit(postfix_expression.at(0))){
//Add the digit so it can become a full number if needed
completeNum+=postfix_expression.at(1);
}
You ask for the postfix_expression.at(1) without ever checking if that element exists. Since there is no check, you might be accessing bad memory locations.