问题
I'm currently making a PHP-program that solves equations. I've divided the input equation into an array so that each line in the array contains one term. (So. [0] = "+5x", [1] = "=", [2] = "-5", [3] = "+10". This is just a basic equation. The script also divides what is in () into sub-arrays. So for example 2x+(5-3x)=3(x+1) [0] = "+2*x", [1] = array([0] = "+5"....
However, I discovered expression trees that is the perfect thing to use in this equation-solver. I've searched the whole internet to learn it, but I can't find any websites that explain it in PHP (I know PHP OOP.). There are lots of pages explaining them in for example C, but as I only know PHP, that is of no help, because I don't understand the example code.
Can anyone here explain everything about expression trees in PHP and some practical example code?
回答1:
Here is the algorithm described. you can implement this in PHP. I don't think anyone already implemented this in PHP (and distribute it as open source)
An example would be:
2*x+3*5-(6+9) = 0
Where:
*
= priority 2+
= priority 1(
= will increase priority of signs by 10+
(second +) = priority 11)
= will decrease priority of signs by 10=
= in this case it is showing that there is another expression (0)
The highest priority is the most important - the one you need to do first
Using these rules you can create an expression tree...
So.. a way in which you have to create the expression and then interpret is:
2 x * 3 5 * + 6 9 + -
Explained:
2 * x | (1)
3 * 5 | (2)
(1) + (2) | (3)
6 + 9 | (4)
(3) - (4) = final
I don't remember exactly how to write a tree I did this to a course in Computer Science but it was something like this:
-
/ \
E (E)
| +
+ / \
/ \ 6 9
E E
| |
* *
/ \ / \
T E T E
| | | |
2 T 3 T
| |
x 5
Now you have to create your own interpreter for this. You can use the interpreter pattern: PHP Interpreter
回答2:
I would suggest you read a bit about the Composite design pattern for your expression trees. The Wikipedia article about it has some UML diagrams and example Java code, which is not so difficult to translate into PHP.
You will probably want to take a look over the Shunting-yard algorithm as well, for parsing your string into the expression tree.
A (very simplistic) PHP example of the expression tree could look like this:
interface INode {
public function getValue();
}
class ValueNode implements INode {
private $val;
function __construct($val) {
$this->val = $val;
}
public function getValue() {
return $this->val;
}
}
class AdditionNode implements INode {
private $op1, $op2;
function __construct($op1, $op2) {
if(!($op1 instanceof INode) or !($op2 instanceof INode)) {
throw new Exception("The operands must implement the INode interface.");
}
$this->op1 = $op1;
$this->op2 = $op2;
}
public function getValue() {
return $this->op1->getValue() + $this->op2->getValue();
}
}
$a = new ValueNode(1);
$b = new ValueNode(5);
$c = new ValueNode(10);
$add1 = new AdditionNode($a, $b);
$add2 = new AdditionNode($add1, $c);
echo $add2->getValue(); // 16
In this case, the INode
interface has just one method that should return the value of the sub-tree rooted in a node.
The ValueNode
class is a simple wrapper to allow numbers to be part of your expression tree (in fact, in PHP you're not restricted to just numbers in the ValueNode
). ValueNode
objects can only serve as leaf nodes in your expression tree.
You start using the composite pattern with the AdditionNode
class, which accepts INode
objects as children and can help you build your expression tree.
You can extend this example further to add other operations, variables, constants etc. which would all implement the INode interface.
回答3:
I built an expression tree in PHP which parses math expressions and tries to solve the problem. You can find the source here http://codehackit.blogspot.com/2011/08/expression-parser-in-php.html
I pretty much explain all the details in that blog post but if you find any ambiguities just ask here ;)
Cheers, hope it helps or at least inspires
回答4:
I wrote a bracket parser for this utility a few years ago - it takes a bracketed SQL WHERE
expression of pretty much any depth, and converts it to PHP Propel code. The whole tarball is here and the expression parsing is kicked off here. The code could be tidier, and bear in mind I'm not familiar with any formal expression analysis techniques - but it works, after a fashion :)
.
来源:https://stackoverflow.com/questions/9762623/how-to-use-expression-trees-in-php