Weekend, looking at the expert system of the book, which has about the rules of the content, suddenly think, can imitate people's learning way to improve computer program computing ability?
Imagine, a little child, he started nothing, first of all, you have to tell him what is the number, and then tell him what is to add, subtract, and then tell him what is multiply, divide, and tell him that the multiplication, in addition to calculate the multiplication first, and then introduced the parentheses, the parentheses are always the first to calculate parentheses. Thus, the more skills he has to tell him, the more he will be able to solve the problem.
So I tried to experiment with it.
The first step is to teach the computer to learn what numbers are.
The following regular expression, is to tell the "child", the number is the front may have "-" number, of course, may not, the next consecutive number 0-9, the number of the composition, there may also be a decimal point to start adding a heap of 0-9 numbers, of course, there is no relationship. So, it even knows how to recognize numbers.
public final class mathnumber { private Mathnumber () { } public static String numberpattern = "[-]? [0-9]+ ([.] [0-9]*)? "; public static pattern pattern = pattern.compile (NumberPattern ); public static matcher match (string string) { matcher match = pattern.matcher (String); if (Match.find ()) { return match; } throw new runtimeexception (string + " is not a number. "); }}
The second step is to tell the child, the process of calculating the maths problem.
If there is a space on both sides, ignore it, then, see if it is already a number, if it is a number, it means that even if the result. If not, start with the highest priority and calculate if you find it. If you can't find it, it means there is a problem, not a valid mathematical formula.
Public static string eval (string string) { string = string.trim (); while (! Ismathnumber (String)) {// which of the same priority is found first, which   SYSTEM.OUT.PRINTLN ("Solution formula:" + string); boolean found = false; for (mathinterface math : mathlist) { Matcher matcher = Math.match (String); if (Matcher.find ()) { &nBsp; string exp = matcher.group (); String sig = ""; if (Exp.charat (0) == '-' && matcher.start () != 0) {// if it is not the first number, the-number can only be used as operator sig = "+"; } SYSTEM.OUT.PRINTLN ("Discovery formula:" + exp); string evalresult = math.eval (exp); string = string.substring (0, matcher.start ()) + sig + evalresult + string.substring (Matcher.end ()); system.out.println ( exp + "Calculated as:" + evalResult + ", Substituting"; ") found = true; break; } } if (!found) { throw new runtimeexception (string + " is not a valid mathematical expression"); } } return string; }
From now on, the child has been able to solve the problem, but he still do not understand, he still do not know what is added, minus, multiply, except what, there is no way, the child stupid, as long as teach him more.
Below teaches him how to calculate, add, subtract, multiply, divide, remainder, parentheses, exponent.
Addmathexpression (New Add ()); Addmathexpression (New Subtract ()); Addmathexpression (New Multiply ()); Addmathexpression (New Devide ()); Addmathexpression (new Minus ()); Addmathexpression (new factorial ()); Addmathexpression (new remainder ()); Addmathexpression (new bracket ()); Addmathexpression (New Power ()); Collections.sort (Mathlist, New Mathcomparator ());
Because of the same similarity, it is only the implementation of the addition and parentheses.
The addition implementation, its priority is 1, it is composed of two numbers in the middle plus a "+" number, the number and the plus sign in front of the space is useless, do not care about it. Calculate the time, is to add the way to add two numbers, this computer is stronger than people, hehe, tell him how to add will never be wrong. and understand that subtraction has an innate advantage.
Public class add implements mathinterface { static string plusPattern = BLANK + MathNumber.numberPattern + BLANK + "[+]{1}" + BLANK + mathnumber.numberpattern + blank; static pattern pattern = pattern.compile (Pluspattern); static pattern plus = Pattern.compile (blank + "\\+"); @Override public matcher match (string string) { return pattern.matcher (String); } @Override public int priority () { return 1; } @Override public string eval (string expression) { matcher a = mathnumber.pattern.matcher ( Expression); if (A.find ()) { expression = expression.substring (A.end ()); } matcher p = plus.matcher (expression); if (P.find ()) { expression = Expression.substring (P.end ()); } matcher b = mathnumber.pattern.matcher (expression); if (B.find ()) { } return new bigdecimal (A.group ()). Add (New bigdecimal (B.group ())) .tostring (); } }
The
is followed by parentheses, and the parentheses have the highest precedence, as long as it should be evaluated first. Of course, the contents of the inner parentheses are calculated first. Parentheses in the content, when the calculation, you can first pull out, no tube outside the content, calculated, put back on it.
Public class bracket implements mathinterface { static String bracketPattern = BLANK + "[(]{1}[^ (]*?[)]" + blank; static pattern pattern = pattern.compile ( Bracketpattern); @Override public matcher match ( string string) { return pattern.matcher (string); } @Override public int Priority () { return Integer.MAX_VALUE; } @Override public string eval ( String expression) { expression = Expression.trim (); Return mathevaluation.eval (Expression.substring (1, expression.length () - 1)); } }
So far, our program "Baby" has learned mathematical calculations, a question let Iraq try.
public static void Main (string[] args) {string string = "1+2^ (4/2) +5%2"; SYSTEM.OUT.PRINTLN ("The result is:" + mathevaluation.eval (String));}
The procedure for your baby's problem is as follows:
Solution equation: 1+2^ (4/2) +5%2 found the equation: (4/2) solve the equation: 4/2 found the equation: The 4/24/2 calculation results are: 2.00, substituting the original (4/2) calculated as: 2.00, substituting the original formula: 1+2^2.00+5%2 found the formula: 2^ 2.002^2.00 calculation results are: 4, the generation of the original formula: 1+4+5%2 found the formula: 5%25%2 calculated as: 1, the generation of the original formula: 1+4+1 found the formula: 1+41+4 calculated as: 5, the return of the original formula: 5+1 the formula: 5+15+ 1 The result of the calculation is: 6, the return of the original result is: 6
Hehe, the program baby's problem-solving process is very consistent with the process of human being, and the implementation of the program is very easy to understand. God horse compilation principle, God horse infix expression is not used. (Execution efficiency is not necessarily high compared to other algorithms, and is only used to verify that the program's processing power is enhanced through rules, and that the regular expressions and program logic are not rigorously written without deep validation due to no in-depth testing)
In fact, although the program is very simple, but, in fact, is a simple rule of the prototype engine.
First, he loads a lot of business processing rules, plus, minus, multiply, divide, interpolate, index, remainder and so on.
Second, his business rules can be extended continuously.
Thirdly, as long as the facts are given, finally, by the constant application of the rules, he will eventually export the result, either the correct result or the fact that it is wrong.
For children who need the source code, please go to git and get the codes directly.
Git address: http://git.oschina.net/tinyframework/mathexp.git
Open source framework That thing 14: teaching computer programs to solve math problems