Expression Tree from Infix Expression in C++ Structural Programming - c++

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

Related

Check if 2 nodes are adjacent in binary tree using linkedlish C++

Sorry for the bad English.
I'm creating a binary tree project by using a linked list in C++. And Im trying to make a boolean method to check if 2 nodes are adjacent or not?
And I'm trying to use the recursion method as I'm using the linked list to do this, but it seems I did it wrong.
Here is how I declare the Node
Struct Node{
string name;
int data;
Node *right, *left;
}
And here is how I declare the checking function:
bool checkadjacent(node* Node, string& u, string& v) {
if(!Node){
return false;
}
if (Node && Node->right) {
string current = Node->name;
string right = Node->right->name;
if (current == u && right == v)
return true;
else if (current == v && right == u)
return true;
}
if (Node && Node->left) {
string current = Node->name;
string left = Node->left->name;
if (current == u && left == v)
return true;
else if (current == v && left == u)
return true;
}
if (Node->left){
if(checkadjacent(Node->left, u, v)){
return true;
}
}
if (Node->right){
if(checkadjacent(Node->right, u, v)){
return true;
}
}
}
Note: "it seems I did it wrong" is not an explanation of how your code fials. Always describe what your code is SUPPOSED to do and what it is ACTUALLY doing.
Having said that, I'm assuming your code does not compile. I put together a (possibly non-comprehensive) list of errors and other problems with your code, aswell as a corrected version of your code. However, I would advise you to watch some tutorials about C++ (or C if you want, since your code is basically C code), because your code shows some serious misunderstandings and neglection. Apart from that, your basic idea seems correct except for the last bullet point in the following list.
List of problems:
It's struct not Struct (capitalization matters in C++). (This is necessary for correctness/syntax)
In the declaration of Node you capitalize the name of the Node. Later, you call it node and instead capitalize the name of the object which instantiates Node (to be consistent, I called the struct Node and it's instantiation node). (This is necessary for correctness/syntax)
First you check whether Node is actually pointing to a struct: if(!Node). This is good, but there is no need to check the same thing again later: if (Node && Node->right) and if (Node && Node->left) just leave out the first part in both conditions: if (node->right) and if (node->left). (This is for style)
Then you can also leave out the 3rd and 4th if statements and put their block into the 1st and 2nd if blocks respectively. (This is for style)
Do not declare the variables current, right and left inside the if blocks, instead declare them at the beginning of the function. (This is for style)
For the algorithm to work you have to return false if none of the if none of the if statements are executed (this is a guess; I did not test this and you WILL have to try that yourself). (This is necessary for correctness/semantics)
Here's the full code (note that I did NOT test this code, as your problem was clearly faulty syntax and not algorithm design.
bool checkadjacent(Node* node, string& u, string& v) {
string current, left, right;
if (!node) {
return false;
}
if (node->right) {
current = node->name;
right = node->right->name;
if (current == u && right == v)
return true;
else if (current == v && right == u)
return true;
// recursion
if (checkadjacent(node->right, u, v)) {
return true;
}
}
if (node->left) {
current = node->name;
left = node->left->name;
if (current == u && left == v)
return true;
else if (current == v && left == u)
return true;
// recursion
if (checkadjacent(node->left, u, v)) {
return true;
}
}
return false;
}
Also note:
I did not change the definition of Node.
Apart from string your code is just C code. In C++ you have the possibility to create a class for the binary tree which would be a lot more readable.
There are no linked lists in any parts of the code above (neither in the code you posted). The fact that the node have left and right child nodes, does not make it a linked list (in particular it's not a list because it is not 1-dimensional).
Again, I did NOT test this code; you can do that yourself.

Converting infix to postfix using c++

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)

Construct binary tree from s-expression in c++

empty tree ::= ()
tree ::= empty tree | (w tree tree)
ex:
()
empty tree
(99(5()())(35(-5()())()))
99
/ \
5 35
/
-5
class Node
{
public:
int weight; // weight can be negative!
Node *left, *right;
Node():weight(0),left(NULL),right(NULL){}
Node(int d):weight(d),left(NULL),right(NULL){}
};
Construct a binary tree by given condition
I get problem with construct it, my program will crush and I have no idea about why it happened, the following is my code and I print out some information for debug, take (99(5()())(35(-5()())())) as a test case, it will print out 99(5( and crush, I think maybe problem is at which I deal with ) where I return node which is NULL, but I can’t find problem with it. By the way, this tree is expected to handle HUNDREDS of nodes in each tree, and Each of the test cases contains up to TEN-THOUSAND trees, will I run out of time with this program or what should I need to do?Thank for your time
Node* MyBinaryTreeOps::constructTree(Node *root, std::string treeStr)const
{
int idex = 1;//always look at the treeStr[1]
Node *cur=NULL;//use to pass in recursive call
if(treeStr[idex]!='('&&treeStr[idex]!=')'){//meet number create new node
stringstream ss;
while(treeStr[idex]!='('){
ss<<treeStr[idex];
if(treeStr.size()>1){//if size > 1 then remove the treeStr[1],to let treeStr[1] become next char in treeStr
treeStr.erase(1,1);
}
}
int num=0;
ss>>num;
std::cout<<num<<std::endl;//print out just for debug
std::cout<<treeStr[idex]<<std::endl;//print out just for debug
root = new Node(num);
}
if(treeStr[idex]==')'){//meet ')' return subtree constructed
if(treeStr.size()>1){
treeStr.erase(1,1);
}
return root;
}
if(treeStr[idex]=='('){//meet first '(' then construct left subtree
if(treeStr.size()>1){
treeStr.erase(1,1);
}
root->left = constructTree(cur,treeStr);
}
if(treeStr[idex]=='('){ //meet second '(' then construct right subtree
if(treeStr.size()>1){
treeStr.erase(1,1);
}
root->right = constructTree(cur,treeStr);
}
if(treeStr[idex]==')'){ //meet ')' return subtree constructed
if(treeStr.size()>1){
treeStr.erase(1,1);
}
return root;
}
}
I've tried this problem by myself and this is the function that I've wrote.
Steps of the algorithm:
Find a part of the sequence that represents weight of current node. Convert it to int and assign to node.
Slice string to remove weight, starting and ending brace.
Iterate over sequence to find point between two braces that divides children nodes.
Split children string into two sequences (We can slice starting tree and reuse it as sequence of one of the children nodes).
If child node has weight (length of its sequence is larger than 2) then create new node and recurse algorithm.
Additionally, here is my program with some test examples and a little bit extended Node class:
Node* constructTree(Node* root, std::string& treeString) {
// Find the weight of this node.
auto weightLeft = treeString.find_first_of("(") + 1;
auto weightRight = treeString.find_first_of("()", weightLeft);
auto weightString = treeString.substr(weightLeft, weightRight - weightLeft);
// Optional, we check if there is any weight, if there is not we leave zero
// weight from constructor.
// Works for something like that: ((1)(2)) -> (0(1)(2))
if (weightString.length() > 0) {
root->weight = std::stoi(weightString);
}
// Slice string to contain only children sequences.
treeString.erase(0, weightRight);
treeString.erase(treeString.length() - 1, 1);
// Looking for index in string where a left child ends and a right child starts.
// This point(index) is located where count of left braces and for braces
// is the same and the counts are not zero.
int splitPoint = -1;
int leftBraces = 0, rightBraces = 0;
for (int index = 0; index < treeString.length(); index++) {
char c = treeString[index];
if (c == '(') {
++leftBraces;
}
if (c == ')') {
++rightBraces;
}
if (leftBraces == rightBraces) {
splitPoint = index + 1;
break;
}
}
// If split point has been found then it means that this node has children.
if (splitPoint != -1) {
auto leftChildString = treeString.substr(0, splitPoint);
auto rightChildString = treeString.erase(0, splitPoint);
// Check for length so construct will stop if there is no child.
if (leftChildString.length() > 2) {
root->left = new Node();
constructTree(root->left, leftChildString);
}
if (rightChildString.length() > 2) {
root->right = new Node();
constructTree(root->right, rightChildString);
}
}
return root;
}

Build binary expression tree C++

I made an algorithm that builds a binary tree from a simple expression. But I need brackets for every action. for example I can convert this expression: (2+(3*5)). In maths everything is ok if there are not any brackets, but my algorithm can work without them. Is there a way to make an algorithm that can make a binary expression tree that works with this expression: 2+3*5?
Here is my algorithm that needs brackets for every action:
void Tree::MakeTree(string expr, int &pos, Node *node)
{
if(expr[pos] == '(')
{
pos++;
node->Left = new Node;
node->Left->Left = NULL;
node->Left->Right = NULL;
MakeTree(expr, pos, node->Left);
MakeTree(expr, pos, node);
return;
}
if(expr[pos] >= '0' && expr[pos] <= '9')
{
node->data = expr[pos];
pos++;
return;
}
if(expr[pos] == '+' || expr[pos] == '-' || expr[pos] == '*' || expr[pos] == '/')
{
node->data = expr[pos];
pos++;
node->Right = new Node;
node->Right->Left = NULL;
node->Right->Right = NULL;
MakeTree(expr, pos, node->Right);
}
if(expr[pos] == ')')
{
pos++;
return;
}
}
If you can offer solution for optimizing my algorithm will be awesome, because I feel that it is not very good.
The way you are trying to solve your problem is too simplified. That would not work. Why? Because how you react on particular symbol depends not only on symbol itself, but in which context you are getting that symbol. So you would have to implement a state machine and in different states you would react differently even to the same input. For example, when you get symbol '-' what is it, part of expression like '5-3' or unary minus from '-6'? It depends in which state you are when you received that symbol. So implementation of full logic of processing syntax parsing is not that simple and which is worse pretty monotonic. That's why in real programs people usually not doing that manually but using special tools like lex/flex or boost library spirit etc. It does not mean you cannot implement that for learning, but answer to that question probably would be too big for stackoverflow format, and it is already answered in many books. So find a good book for syntax parsing or try to find tutorial on internet how to implement a simple calculator.

Need to create infix to postfix algorithm

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