Автор: Пользователь скрыл имя, 29 Октября 2012 в 15:03, курсовая работа
Бурхливий розвиток обчислювальної техніки висунуло на передній план при вирішенні практичних інженерних і наукових задач обчислювальну математику і програмування.
Обчислювальна математика вивчає побудову та дослідження чисельних методів розв'язання математичних задач за допомогою реалізації відповідних математичних моделей.
Програмування забезпечує технічну реалізацію їх.
return (newNode(exp));
}
elseif (isAllNumbers(exp)) // this is really the only place where isAllNumbers matters.
{
try
{
return (newNode(Double.Parse(exp)));
}
catch (FormatException)
{
thrownew System.Exception("Syntax error-> " + exp + " (not using regional decimal separator?)");
}
}
while (i < len)
{
if ((fop = getOp(exp, i)) == null)
{
farg = arg(null, exp, i);
fop = getOp(exp, i + farg.Length);
if (fop == null) thrownewException("Missing operator");
if (isTwoArgOp(fop))
{
sarg = arg(fop, exp, i + farg.Length + fop.Length);
if (sarg.Equals("")) thrownewException("Wrong number of arguments to operator " + fop);
tree = newNode(fop, parse(farg), parse(sarg));
i += farg.Length + fop.Length + sarg.Length;
}
else
{
if (farg.Equals("")) thrownewException("Wrong number of arguments to operator " + fop);
tree = newNode(fop, parse(farg));
i += farg.Length + fop.Length;
}
}
else
{
if (isTwoArgOp(fop))
{
farg = arg(fop, exp, i + fop.Length);
if (farg.Equals("")) thrownewException("Wrong number of arguments to operator " + fop);
if (tree == null)
{
if (fop.Equals("+") || fop.Equals("-"))
{
}
else
{
thrownewException("Wrong number of arguments to operator " + fop);
}
}
tree = newNode(fop, tree, parse(farg));
i += farg.Length + fop.Length;
}
else
{
farg = arg(fop, exp, i + fop.Length);
if (farg.Equals("")) thrownewException("Wrong number of arguments to operator " + fop);
tree = newNode(fop, parse(farg));
i += farg.Length + fop.Length;
}
}
}
return tree;
}
///<summary>
/// Parses the infix expression for arguments to the specified operator.
///</summary>
///<param name="_operator">the operator we are interested in</param>
///<param name="exp">the infix string expression</param>
///<param name="index">the index to start the search from</param>
///<returns>the argument to the operator</returns>
privateString
arg(String _operator, String exp, int index)
{
int ma, i, prec = -1;
int len = exp.Length;
String op = null;
StringBuilder str = newStringBuilder(sb_init);
i = index;
ma = 0;
if (_operator == null)
{
prec = -1;
}
else
{
prec = ((Operator)ops[_operator]).
}
while (i < len)
{
if (exp[i] == '(')
{
ma = match(exp, i);
str.Append(exp.Substring(i, ma + 1 - i));
i = ma + 1;
}
elseif ((op = getOp(exp, i)) != null)
{
// (_operator != null && _operator.Equals("&&") && op.Equals("||") ) ||
if (str.Length != 0 && !isTwoArgOp(backTrack(str.
{
return str.ToString();
}
str.Append(op);
i += op.Length;
}
else
{
str.Append(exp[i]);
i++;
}
}
return str.ToString();
}
///<summary>
/// Returns an operator at the end of the String str if present.
///</summary>
///<remarks>
/// Used when parsing for arguments, the purpose is to recognize
/// expressions like for example 10^-1
///</remarks>
///<param name="str">part of infix string expression to search</param>
///<returns>the operator if found or null otherwise</returns>
privateString
backTrack(String str)
{
int i = 0;
int len = str.Length;
String op = null;
try
{
for (i = 0; i <= maxoplength; i++)
{
if ((op = getOp(str, (len - 1 - maxoplength + i))) != null
&& (len - maxoplength - 1 + i + op.Length) == len)
{
return op;
}
}
}
catch { }
returnnull;
}
///<summary>
/// Calculates the faculty.
///</summary>
///<remarks>
/// This method should move out of this class since it has nothing to do with the parser.
/// it's here because the language math functions do not include faculty calculations.
///</remarks>
///<param name="val">the value to calcualte the faculty of</param>
///<returns>the faculty</returns>
privatedouble
fac(double val)
{
if (!isInteger(val))
{
returnDouble.NaN;
}
elseif (val < 0)
{
returnDouble.NaN;
}
elseif (val <= 1)
{
return 1;
}
return (val * fac(val - 1));
}
///<summary>
/// Calculates the semi faculty.
///</summary>
///<remarks>
/// This method should move out of this class since it has nothing to do with the parser.
/// it's here because the language math functions do not include semi faculty calculations.
///</remarks>
///<param name="val">the value to calcualte the semi faculty of</param>
///<returns>the semi faculty</returns>
privatedouble
sfac(double val)
{
if (!isInteger(val))
{
returnDouble.NaN;
}
elseif (val < 0)
{
returnDouble.NaN;
}
elseif (val <= 1)
{
return 1;
}
return (val * sfac(val - 2));
}
///<summary>
/// Returns the decimal part of the value
///</summary>
///<param name="val">the value to calculate the fpart for</param>
///<returns>the decimal part of the value</returns>
privatedouble
fpart(double val)
{
if (val >= 0)
{
return (val - Math.Floor(val));
}
else
{
return (val - Math.Ceiling(val));
}
}
///<summary>
/// Parses the datastructure created by the parse method.
///</summary>
///<remarks>
/// This is where the actual evaluation of the expression is made,
/// the Node tree structure created by the parse method is recursed and evaluated
/// to a double value.
///</remarks>
///<param name="tree">A Node representing a tree datastructure</param>
///<returns>A double value</returns>
privatedouble
toValue(Node tree)
{
Node arg1, arg2;
double val;
String op, tmp, var;
if (tree.getType() == Node.TYPE_CONSTANT)
{
return (tree.getValue());
}
elseif (tree.getType() == Node.TYPE_VARIABLE)
{
var = tree.getVariable();
// check if PI, Euler....etc
if (spconst.ContainsKey(var))
{
return ((double)spconst[var]);
}
// not built in variable, get value
tmp = get(var);
if (trees.ContainsKey(tmp))
{
return toValue((Node)trees[tmp]);
}
elseif (isConstant(tmp))
{
return (Double.Parse(tmp));
}
else
{
// apparently a nested expression, parse and cache
tmp = skipSpaces(tmp.ToLower());
htbl[var] = tmp;
Syntax(tmp);
tree = parse(putMult(parseE(tmp)));
trees.Add(tmp, tree);
return toValue(tree);
}
}
op = tree.getOperator();
arg1 = tree.arg1();
if (tree.arguments() == 2)
{
arg2 = tree.arg2();
if (op.Equals("+"))
return (toValue(arg1) + toValue(arg2));
elseif (op.Equals("-"))
return (toValue(arg1) - toValue(arg2));
elseif (op.Equals("*"))
return (toValue(arg1) * toValue(arg2));
elseif (op.Equals("/"))
return (toValue(arg1) / toValue(arg2));
elseif (op.Equals("^"))
return (Math.Pow(toValue(arg1), toValue(arg2)));
elseif (op.Equals("log"))
return (Math.Log(toValue(arg2)) / Math.Log(toValue(arg1)));
elseif (op.Equals("%"))
return (toValue(arg1) % toValue(arg2));
elseif (op.Equals("=="))
return (toValue(arg1) == toValue(arg2) ? 1.0 : 0.0);
elseif (op.Equals("!="))
return (toValue(arg1) != toValue(arg2) ? 1.0 : 0.0);
elseif (op.Equals("<"))
return (toValue(arg1) < toValue(arg2) ? 1.0 : 0.0);
elseif (op.Equals(">"))
return (toValue(arg1) > toValue(arg2) ? 1.0 : 0.0);
elseif (op.Equals("&&"))
return ((toValue(arg1) == 1.0) && (toValue(arg2) == 1.0) ? 1.0 : 0.0);
elseif (op.Equals("||"))
return ((toValue(arg1) == 1.0) || (toValue(arg2) == 1.0) ? 1.0 : 0.0);
elseif (op.Equals(">="))
return (toValue(arg1) >= toValue(arg2) ? 1.0 : 0.0);
elseif (op.Equals("<="))
return (toValue(arg1) <= toValue(arg2) ? 1.0 : 0.0);
}
else
{
if (op.Equals("sqrt"))
return (Math.Sqrt(toValue(arg1)));
elseif (op.Equals("sin"))
return (Math.Sin(toValue(arg1)));
elseif (op.Equals("cos"))
return (Math.Cos(toValue(arg1)));
elseif (op.Equals("tan"))
return (Math.Tan(toValue(arg1)));
elseif (op.Equals("asin"))
return (Math.Asin(toValue(arg1)));
elseif (op.Equals("acos"))
return (Math.Acos(toValue(arg1)));
elseif (op.Equals("atan"))
return (Math.Atan(toValue(arg1)));
elseif (op.Equals("ln"))
return (Math.Log(toValue(arg1)));
elseif (op.Equals("exp"))
return (Math.Exp(toValue(arg1)));
elseif (op.Equals("cotan"))
return (1 / Math.Tan(toValue(arg1)));
elseif (op.Equals("acotan"))
return (Math.PI / 2 - Math.Atan(toValue(arg1)));
elseif (op.Equals("ceil"))
return ((double)Math.Ceiling(toValue(
elseif (op.Equals("round"))
return ((double)Math.Round(toValue(
elseif (op.Equals("floor"))
return ((double)Math.Floor(toValue(
elseif (op.Equals("fac"))
return (fac(toValue(arg1)));
elseif (op.Equals("abs"))
return (Math.Abs(toValue(arg1)));
elseif (op.Equals("fpart"))
return (fpart(toValue(arg1)));
elseif (op.Equals("sfac"))
return (sfac(toValue(arg1)));
elseif (op.Equals("sinh"))
{
val = toValue(arg1);
return ((Math.Exp(val) - (1 / Math.Exp(val))) / 2);
}
elseif (op.Equals("cosh"))
{
val = toValue(arg1);
return ((Math.Exp(val) + (1 / Math.Exp(val))) / 2);
}
elseif (op.Equals("tanh"))
{
val = toValue(arg1);
return (((Math.Exp(val) - (1 / Math.Exp(val))) / 2) / ((Math.Exp(val) + (1 / Math.Exp(val))) / 2));
}
elseif (op.Equals("!"))
{
return ((!(toValue(arg1) == 1.0)) ? 1.0 : 0.0);
}
}
thrownew System.Exception("Unknown operator");
}
///<summary>
/// Retrieves a value stored in the Hashtable containing all variable = value pairs.
///</summary>
///<remarks>
/// The hashtable used in this method is set by the Parse( String, Hashtable ) method so this method retrives
/// values inserted by the user of this class. Please note that no processing has been made
/// on these values, they may have incorrect syntax or casing.
///</remarks>
///<param name="key">the name of the variable we want the value for</param>
///<returns>the value stored in the Hashtable or null if none.</returns>
privateString
get(String key)
{
Object ob = this.htbl[key];
String val = null;
if (ob == null) thrownew System.Exception("No value associated with " + key);
try
{
val = (String)ob;
}
catch
{
thrownew System.Exception("Wrong type value for " + key + " expected String");
}
return (val);
}
///<summary>
/// Evaluates the infix expression using the values in the Hashtable.
///</summary>
///<remarks>
/// This is the only publicly available method of the class, it is the entry point into for the user
/// into the parser.
///
/// Example usage:
///
/// using info.lundin.Math;
/// using System;
/// using System.Collections;
///
/// public class Test
/// {
/// public static void Main( String[] args )
/// {
/// ExpressionParser parser = new ExpressionParser();
/// Hashtable h = new Hashtable();
///
/// h.Add( "x", 1.ToString() );
/// h.Add( "y", 2.ToString() );
///
///
/// double result = parser.Parse( "xcos(y)", h );
/// Console.WriteLine( “Result: {0}”, result );
/// }
/// }
///
///</remarks>
///<param name="exp">the infix string expression to parse and evaluate.</param>
///<param name="tbl">Hashtable with variable value pairs</param>
///<returns>a double value</returns>
publicdouble
Parse(String exp, Hashtable tbl)
{
double ans = 0D;
String tmp;
Node tree;
if (exp == null || exp.Equals(""))
{
thrownew System.Exception("First argument to method eval is null or empty string");
}
elseif (tbl == null)
{
return Parse(exp, newHashtable());
}
this.htbl = tbl;
tmp = skipSpaces(exp.ToLower());
this.sb_init = tmp.Length;
try
{
if (trees.ContainsKey(tmp))
{
ans = toValue((Node)trees[tmp]);
}
else
{
Syntax(tmp);
tree = parse(putMult(parseE(tmp)));
ans = toValue(tree);
trees.Add(tmp, tree);
}
return ans;
}
catch (Exception e)
{
thrownew System.Exception(e.Message);
}
}
} // End class ExpressionParse
publicclassNode
{
///<summary>Represents the type variable</summary>
publicstaticint TYPE_VARIABLE = 1;
///<summary>Represents the type constant ( numeric value )</summary>
publicstaticint TYPE_CONSTANT = 2;
///<summary>Represents the type expression</summary>
publicstaticint TYPE_EXPRESSION = 3;
///<summary>Reserved</summary>
publicstaticint TYPE_END = 4;
///<summary>Used as initial value</summary>
publicstaticint TYPE_UNDEFINED = -1;
privateString _operator = "";
privateNode _arg1 = null;
privateNode _arg2 = null;
privateint args = 0;
privateint type = TYPE_UNDEFINED;
privatedouble value = Double.NaN;
privateString variable = "";
///<summary>
/// Creates a Node containing the specified Operator and arguments.
/// This will automatically mark this Node as a TYPE_EXPRESSION
///</summary>
///<param name="_operator">the string representing an operator</param>
///<param name="_arg1">the first argument to the specified operator</param>
///<param name="_arg2">the second argument to the specified operator</param>
public Node(String _operator, Node _arg1, Node _arg2)
{
this._arg1 = _arg1;
this._arg2 = _arg2;
this._operator = _operator;
this.args = 2;
this.type = TYPE_EXPRESSION;
}
///<summary>
/// Creates a Node containing the specified Operator and argument.
/// This will automatically mark this Node as a TYPE_EXPRESSION
///</summary>
///<param name="_operator">the string representing an operator</param>
///<param name="_arg1">the argument to the specified operator</param>
public Node(String _operator, Node _arg1)
{
this._arg1 = _arg1;
this._operator = _operator;
this.args = 1;
this.type = TYPE_EXPRESSION;
}
///<summary>
/// Creates a Node containing the specified variable.
/// This will automatically mark this Node as a TYPE_VARIABLE
///</summary>
///<param name="variable">the string representing a variable</param>
public Node(String variable)
{
this.variable = variable;
this.type = TYPE_VARIABLE;
}
///<summary>
/// Creates a Node containing the specified value.
/// This will automatically mark this Node as a TYPE_CONSTANT
///</summary>
///<param name="value">the value for this Node</param>
public Node(double value)
{
this.value = value;
this.type = TYPE_CONSTANT;
}
///<summary>
/// Returns the String operator of this Node
///</summary>
publicString getOperator()
{
return (this._operator);
}
///<summary>
/// Returns the value of this Node
///</summary>
publicdouble getValue()