![]() |
General Programming »
Algorithms & Recipes »
Math
Intermediate
License: The Code Project Open License (CPOL)
Dynamic Formula Processing LibraryBy Derek BartramAn article presenting a basic dynamic formula processor (including an infix to prefix convertor) |
C# (C# 1.0, C# 2.0, C# 3.0), Windows (Win2K, WinXP, Win2003, Vista), .NET CF, .NET (.NET 1.0, .NET 1.1, .NET 2.0, .NET 3.0, .NET 3.5), Win32, Win64, Architect, Dev, QA, Design
|
||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

This library evaluates formulas in strings to a value, e.g. "2+4*6+2" returns 28.
Simply put infix notation is the notation used by use mere mortals, e.g. 2+4*6+2. In infix notation the operator (e.g. + or *) is inside the operands (e.g. 2, 4, and 6). While this notation is simple for a human to understand it is not so convienient for processing, as the computer typically needs to know what to do before it gets the specifics of what the operand values actually are, hence prefix notation.
Prefix notation or a variation of is used by most programming languages and processing arithmetic logic units (ALU), and can be defined as operator operand_1 operand_2 operand_3 and so on. Consider the following infix formula 2 + 4 * 6 + 2, this can be shown in prefix notation as + 2 + * 4 6 2, or perhaps more logically as a tree;
Processing is then performed as + 2 (+ (* 4 6) 2), with evaluation of the formula proceeding up the tree;
The tree structure representation of prefix forms the basis for this library, however it is undesirable to ask user input in this form due to limit comprehension by the general lay-person.
Infix to prefix conversation is performed on a stack using a tokenisor (in this case generating tokens via space edges).
Courtesy of Expressions, Conversion and Evaluation with C.
Suppose we want to convert 2 + 4 * 6 + 2 into Prefix form: Reversed Expression: 2 + 6 * 4 + 2
| Current Token | Stack Contents (Top on Right) | Prefix Expression (Right to Left) |
|---|---|---|
| 2 | 2 | |
| + | + | 2 |
| 4 | + | 2 4 |
| 4 | + | 2 4 |
| * | + * | 2 4 |
| 6 | + * | 2 4 6 |
| + | + + | 2 4 6 * |
| 2 | + + | 2 4 6 * 2 |
| + | 2 4 6 * 2 + | |
| 2 4 6 * 2 + + |
Reverse the output string : + + 2 * 4 6 2
Each mathematical operator is encapsulated via a class containing the operator and all operands needed by the operator (remembering that the operands may be other mathematical operators and operands), thus allowing the tree pattern as above.
Note: in this implementation of dynamic formula processing, not only may the standard mathematical operators and values be processed, but constants (e.g. x and y) as well. In terms of infix to prefix conversion, values and constants are treated in the same way as during this process the value of the token is not important in so much as the type is more important.
Each operator class contains the following methods;
The parse method proceeds as follows (* assuming an operator requiring two operands);
Thus, processing may complete as follows;
Once complete a tree data structure is formed as follows for the example 2 + 4 * 6 + 2 or + + 2 * 4 6 2;
<add><add>2, <multiply>4, 6</multiply></add>, 2</add>
And hence calling the recursive evaluate method performs;
In cases where constants are performed, the evaluate method performs a lookup in the supplied Hashtable.
The library supplied can evaluate mathematic functions + - * / ^(power).
In addition;
To use the library simply create a new Formula giving the formula string in the constructor. Calling evaluate with a Hashtable on constants (or new Hashtable() if none exist) returns the formula result.
Is this the best way to evaluated formulas dynamically? No, the performance of this approach is not good when many formulas are to be processed due to the high number of method calls when evaluating. However, this method is particularly beneficial when using in conjunction with genetic algorithms (evolutionary algorithms) due to the ease of mutation and crossover. My next article on the subject will show how to use this library to generate a curve function that automatically fits ANY trend.
Version 1.0.0.0 - Initial build
Please feel free to use this in your work, however please be aware that a modified The Code Project Open License (CPOL) is in use; basically it is the same as the standard license except that this code must not be used for commercial or not-for-profit commercial use without prior authorisation. Please see license.txt or license.pdf in the included source and demo files.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 25 Apr 2008 Editor: |
Copyright 2008 by Derek Bartram Everything else Copyright © CodeProject, 1999-2009 Web22 | Advertise on the Code Project |