Build binary expression tree C++ - 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.

Related

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)

Expression Tree from Infix Expression in C++ Structural Programming

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

How to replace data in a certain node in a linked list?

I have an exercise using linked lists for my class. I am fairly new to the language, but I've given it an attempt. The instructions tell us to "iterate through until NodeData is found, then replace the data using the sets."
What are "the sets" in C++? I've looked online and I couldn't find anything. The only thing I can think of is setting the nodes to point somewhere else. For example head->NULL. But is this really necessary if I am simply replacing the data? To replace the data I've tried temp->order = NEWDATA. Is that the correct implementation? It did not seem to work. Maybe it was an error in a different part of the code.
bool OrderLL::Modify(Order * NodeData) {
OrderNode *temp = head;
if (temp == NULL) {
cout << "Empty List";
}
else {
while (temp != NULL) {
if (temp->order == NodeData) {
//not sure if this is the proper way of deleting data inside a node
delete anOrder;
//HOW DO I REPLACE THE DATA IN THIS PART?
}
temp = temp->next;
}
}
return false;
}
On a side note, I really do not understand why I continue to recieve downvotes on all my questions. Is it because they're basic C++ questions? They're not so basic to me. I know this website looks down upon "offtopic/chat discussions" but I just don't understand what is wrong with my questions.
You mentioned "replace" in your question, so just taking a guess but might be you are expected to replace the node itself and not just the data. In which case, it will be something like this
if(curr_node->data == to_replace_data){
curr_node->next = new_node;
new_node->next = curr_node->next->next;
free( curr_node->next); //or return curr_node->next depending on what
// you are trying to do.
}

Huffman Coding - Incorrect Codes

Im trying to build a Huffman tree using an array. Everytime i combine two nodes, I add the new node to the array and sort it. My code works for some test cases but for others, it produces the wrong codes. Can someone please point me to the right direct in debugging? Thanks!
Here is a segment of my compress function.
while(tree->getSize() != 1)
{
right = tree->getMinNode();
left = tree->getMinNode();
Node *top = new Node;
top->initializeNode((char)1, left->getFrequency() + right->getFrequency(), left, right);
tree->insertNode(top);
} // while
root = tree->getRootNode();
tree->encodeTree(root, number, 0);
tree->printCode(data);
The getMinNode() function returns the smallest node and after I insert the node that combines the 2 smallest nodes, I use qsort to sort the array. This is the function i use to sort the array.
I am sorting: 1st with frequency, 2nd with data. If the node is not a leaf node, meaning it does not contain one of the characters presented in the uncompressed data, I find the minimum data in the subtree using the function getMinData().
int Tree::compareNodes(const void *a, const void *b)
{
if( ((Node *)a)->frequency < ((Node *)b)->frequency )
return -1;
if( ((Node *)a)->frequency > ((Node *)b)->frequency )
return 1;
if( ((Node *)a)->frequency == ((Node *)b)->frequency )
{
if( ((Node *)a)->isLeafNode() && ((Node *)b)->isLeafNode() )
{
if( (int)((Node *)a)->data < (int)((Node *)b)->data )
return -1;
if( (int)((Node *)a)->data > (int)((Node *)b)->data )
return 1;
} // if
else
{
int minA, minB;
minA = (int)((Node *)a)->data;
minB = (int)((Node *)b)->data;
if(!((Node *)a)->isLeafNode())
getMinData(a, &minA);
if(!((Node *)b)->isLeafNode())
getMinData(b, &minB);
if(minA < minB)
return -1;
if(minA > minB)
return 1;
}// else
} // if
return 0;
} // compareNodes()
Say if for example, i have the following text.
I agree that Miss Emily Grierson is a symbol of the Old South. Her house and family traditions support this suggestion. However, I do not see her as a victim of the values of chivalry, formal manners, and tradition. I consider these values to have positive effects of a person rather have negative impacts. If for any reason that had made Emily isolate herself from her community and ultimately kill a man she likes, it would be herself. She acts as her own antagonist in the story because she does not have conflict with anyone else except herself. She makes herself become a “victim,” as in being friendless and miserable. The traditions and manners taught to her may have effects on her behavior but it is her attitude towards the outside world that separates her from the rest of the townspeople
\n
with the '\n' at the end. some of the characters i get the correct huffman codes, but some others i don't. Ascii 83('S'), 120('x'), 84('T') are some of the characters with the wrong codes. Thanks!

Floyd's cycle-finding algorithm

I'm trying to find this algorithm on C++ in .NET but can't, I found this one:
// Best solution
function boolean hasLoop(Node startNode){
Node slowNode = Node fastNode1 = Node fastNode2 = startNode;
while (slowNode && fastNode1 = fastNode2.next() && fastNode2 = fastNode1.next()){
if (slowNode == fastNode1 || slowNode == fastNode2) return true;
slowNode = slowNode.next();
}
return false;
}
but doesn't seem to be right, or am I wrong? How can I actually prove that my hare will meet tortoise at the end? Thanks in advance for any explanation how exactly does it work and proof
EDITED
About this solution, I found that in regular algorithm they use only one fast iterator but here they use two, why?
The idea in the code you've found seems fine. Two fast iterators are used for convenience (although I'm positive such kind of 'convenience', like putting a lot of 'action' in the condition of while loop, should be avoided). You can rewrite it in more readable way with one variable:
while (fastNode && fastNode.next()) {
if (fastNode.next() == slowNode || fastNode.next().next() == slowNode) {
return true;
}
fastNode = fastNode.next().next();
slowNode = slowNode.next();
}
The algorithm is correct. Proof:
The case of no cycle is trivial: the hare will find the end of the list.
So, there's a cycle, and the hare enters it, running around like crazy. Eventually, the tortoise reaches the first node of the cycle. From this point on, both necessarily stay in the cycle: the only way they can go from a node is to the next node, which eventually leads back to the first node of the cycle. (Draw a picture of the list/graph to convince yourself.)
Since the hare moves faster, it will eventually catch up with the tortoise. Depending on the length of the cycle and the number of nodes traversed before entering it (whether they are odd or even is what matters, so there are four cases), this may happen after an odd or an even number of steps. That's why the hare should check both its current node and the next node for the tortoise's presence. (The example code uses two pointers to achieve this, though that's not really necessary.)
For a more formal proof, check out this Wikipedia page.
This algorithm will find a cycle in a linked list.
one fast node can be used instead:
function boolean hasLoop(Node startNode){
Node slowNode = Node fastNode = startNode;
while (slowNode && fastNode = fastNode.next() && fastNode = fastNode.next()){
if (slowNode == fastNode) return true;
slowNode = slowNode.next();
}
return false;
}