Hmm, well, what you are being asked to do is some pretty basic transformations.
• First you must transform a line of text (given to you by the user) into a tree structure.
• Then you must transform that tree structure to apply some calculus to it.
• Finally you must transform the tree structure back to a textual string and print it for the user.
Example Time
Given an input stream containing the following tokens (this is your example problem):
5 * x ^ 2 + 6 * x / y - 10 * x ^ 2 * y + 100
You must transform that into something that you can manipulate. We have all recommended a basic binary tree.
In the following, I am going to reorganize the equation by wrapping it in parentheses (). When a change is made, I will use square brackets [] to highlight what has changed. The basic structure is this:
(operation left-operand right-operand)
For example, (+ 5 7) means add five and seven. This is the basis of our
binary tree.
Let’s transform the equation:
Given
5 * x ^ 2 + 6 * x / y - 10 * x ^ 2 * y + 100
First, handle exponents, left to right
5 * x ^ 2 + 6 * x / y - 10 * x ^ 2 * y + 100
↑
5 * [^ x 2] + 6 * x / y - 10 * x ^ 2 * y + 100
↑
5 * (^ x 2) + 6 * x / y - 10 * [^ x 2] * y + 100
Next, handle multiplication and division, left to right
5 * (^ x 2) + 6 * x / y - 10 * (^ x 2) * y + 100
↑
[* 5 (^ x 2)] + 6 * x / y - 10 * (^ x 2) * y + 100
↑
(* 5 (^ x 2)) + [* 6 x] / y - 10 * (^ x 2) * y + 100
↑
(* 5 (^ x 2)) + [/ (* 6 x) y] - 10 * (^ x 2) * y + 100
↑
(* 5 (^ x 2)) + (/ (* 6 x) y) - [* 10 (^ x 2)] * y + 100
↑
(* 5 (^ x 2)) + (/ (* 6 x) y) - [* (* 10 (^ x 2)) y] + 100
Finally, handle addition and subtraction, left to right
(* 5 (^ x 2)) + (/ (* 6 x) y) - (* (* 10 (^ x 2)) y) + 100
↑
[+ (* 5 (^ x 2)) (/ (* 6 x) y)] - (* (* 10 (^ x 2)) y) + 100
↑
[- (+ (* 5 (^ x 2)) (/ (* 6 x) y)) (* (* 10 (^ x 2)) y)] + 100
↑
[+ (- (+ (* 5 (^ x 2)) (/ (* 6 x) y)) (* (* 10 (^ x 2)) y)) 100]
|
We can see this is correct with a little pretty-printing:
(+
(-
(+
(*
5
(^ x 2))
(/
(* 6 x)
y))
(*
(*
10
(^ x 2))
y))
100)
|
The outermost operation is an addition, which is applied after evaluating both operands — Visually, you can see that the 100 is added after everything else is computed.
Turning that into Code
In code, you must represent this binary tree in some way. Here is an easy one that knows how to take care of its own memory (no pointers necessary):
1 2 3 4 5 6
|
struct Node
{
enum { Constant, Variable, Operator } type;
std::string value;
std::vector <Node> operands;
};
|
So, I can create a node that represents, say, a coefficient:
1 2 3
|
Node coef;
coef.type = Constant;
coef.value = "7";
|
Or a node that represents a variable:
1 2 3
|
Node var;
var.type = Variable;
var.value = "x";
|
Or a node that represents a binary operation, like multiplication:
1 2 3 4 5
|
Node mul;
mul.type = Operator;
mul.value = "*";
mul.operands.push_back( coef );
mul.operands.push_back( var );
|
This last node is the same as (* 7 x), which is the same as "7 * x".
Review
So, the
first thing you need to do is:
• Tokenize a text stream into a binary tree
• Print the binary tree
Unless you want to get deep into recursive-descent parsing, I recommend you use the binary tree as your basis for tokens, then modify the tree until it is properly transformed.
This means cheating a little with the pieces of your structure. Start with a flat list, using operands for the list of tokens.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
struct Node
{
enum { Tokens, Constant, Variable, Operator } type;
std::string value;
std::vector <Node> operands;
Node( int type, std::string value ): type(type), value(value) { }
};
bool get_token( const std::string& s, int& n, Node& token )
{
...
}
Node read_tokens( const std::string& s )
{
int n = 0;
Node result;
Node token;
while (get_token( s, n, token ))
result.operands.push_back( token );
return result;
}
|
So, at this point you have a flat list of tokens, which you must build into a tree. It works just like the example above — keep making passes over the tree and combining elements of the token list into proper nodes, starting with exponents, until all you have left is a proper tree.
Well, I’m off to eat dinner.
Hope this helps get you started.