Автор: Пользователь скрыл имя, 29 Октября 2012 в 15:03, курсовая работа
Бурхливий розвиток обчислювальної техніки висунуло на передній план при вирішенні практичних інженерних і наукових задач обчислювальну математику і програмування.
Обчислювальна математика вивчає побудову та дослідження чисельних методів розв'язання математичних задач за допомогою реалізації відповідних математичних моделей.
Програмування забезпечує технічну реалізацію їх.
ops.Add("asin", newOperator("asin", 1, 2));
ops.Add("atan", newOperator("atan", 1, 2));
ops.Add("cosh", newOperator("cosh", 1, 2));
ops.Add("sinh", newOperator("sinh", 1, 2));
ops.Add("tanh", newOperator("tanh", 1, 2));
ops.Add("sqrt", newOperator("sqrt", 1, 2));
ops.Add("cotan", newOperator("cotan", 1, 2));
ops.Add("fpart", newOperator("fpart", 1, 2));
ops.Add("acotan", newOperator("acotan", 1, 2));
ops.Add("round", newOperator("round", 1, 2));
ops.Add("ceil", newOperator("ceil", 1, 2));
ops.Add("floor", newOperator("floor", 1, 2));
ops.Add("fac", newOperator("fac", 1, 2));
ops.Add("sfac", newOperator("sfac", 1, 2));
ops.Add("abs", newOperator("abs", 1, 2));
ops.Add("log", newOperator("log", 2, 5));
ops.Add("%", newOperator("%", 2, 4));
ops.Add(">", newOperator(">", 2, 7));
ops.Add("<", newOperator("<", 2, 7));
ops.Add("&&", newOperator("&&", 2, 8));
ops.Add("==", newOperator("==", 2, 7));
ops.Add("!=", newOperator("!=", 2, 7));
ops.Add("||", newOperator("||", 2, 9));
ops.Add("!", newOperator("!", 1, 1));
ops.Add(">=", newOperator(">=", 2, 7));
ops.Add("<=", newOperator("<=", 2, 7));
// Constants
spconst.Add("euler", Math.E);
spconst.Add("pi", Math.PI);
spconst.Add("nan", double.NaN);
spconst.Add("infinity", double.PositiveInfinity);
spconst.Add("true", 1D);
spconst.Add("false", 0D);
// maximum operator length, used when parsing.
maxoplength = 6;
// init all StringBuilders with this value.
// this will be set to the length of the expression being evaluated by Parse.
sb_init = 50;
}
///<summary>Matches all paranthesis and returns true if they all match or false if they do not.</summary>
///<param name="exp">expression to check, infix notation</param>
///<returns>true if ok false otherwise</returns>
privatebool
matchParant(String exp)
{
int count = 0;
int i = 0;
int l = exp.Length;
for (i = 0; i < l; i++)
{
if (exp[i] == '(')
{
count++;
}
elseif (exp[i] == ')')
{
count--;
}
}
return (count == 0);
}
///<summary>Checks if the character is alphabetic.</summary>
///<param name="ch">Character to check</param>
///<returns>true or false</returns>
privatebool
isAlpha(char ch)
{
return ((ch >= 'a'&& ch <= 'z') || (ch >= 'A'&& ch <= 'Z'));
}
///<summary>Checks if the string can be considered to be a valid variable name.</summary>
///<param name="str">The String to check</param>
///<returns>true or false</returns>
privatebool
isVariable(String str)
{
int i = 0;
int len = str.Length;
if (isAllNumbers(str)) returnfalse;
for (i = 0; i < len; i++)
{
if (getOp(str, i) != null || isAllowedSym(str[i]))
{
returnfalse;
}
}
returntrue;
}
///<summary>Checks if the character is a digit</summary>
///<param name="ch">Character to check</param>
///<returns>true or false</returns>
privatebool
isConstant(char ch)
{
return (Char.IsDigit(ch));
}
///<summary>Checks to se if a string is numeric</summary>
///<param name="exp">String to check</param>
///<returns>true if the string was numeric, false otherwise</returns>
privatebool
isConstant(String exp)
{
double val = 0D;
bool ok = Double.TryParse(exp, out val);
return (ok && !Double.IsNaN(val));
/*try
{
if( Double.IsNaN( Double.Parse( exp ) ) )
{
return false;
}
}
catch
{
return false;
}
return true;*/
}
///<summary>
/// Checks to see if this String consists of only digits and punctuation.
///</summary>
///<remarks>
/// NOTE: needed in .NET at all ? This is a legacy from the Java version
/// where it was needed because some older JVM's accepted strings that started
/// with digits as numeric when the isConstant method was used.
///</remarks>
///<param name="str">The string to check</param>
///<returns>true if the string was numeric, false otherwise.</returns>
privatebool
isAllNumbers(String str)
{
char ch;
int i = 0, l = 0;
bool dot = false;
ch = str[0];
if (ch == '-' || ch == '+') i = 1;
l = str.Length;
while (i < l)
{
ch = str[i];
if (!(Char.IsDigit(ch) || ((ch == '.' || ch == ',') && !dot)))
{
returnfalse;
}
dot = (ch == '.' || ch == ',');
i++;
}
returntrue;
}
///<summary>
/// Checks to see if the string is the name of a acceptable operator.
///</summary>
///<param name="str">The string to check</param>
///<returns>true if it is an acceptable operator, false otherwise.</returns>
privatebool
isOperator(String str)
{
return (ops.ContainsKey(str));
}
///<summary>
/// Checks to see if the operator name represented by str takes two arguments.
///</summary>
///<param name="str">The string to check</param>
///<returns>true if the operator takes two arguments, false otherwise.</returns>
privatebool
isTwoArgOp(String str)
{
if (str == null) returnfalse;
Object o = ops[str];
if (o == null) returnfalse;
return (((Operator)o).arguments() == 2);
}
///<summary>
/// Checks to see if the double value a can be considered to be a mathematical integer.</summary>
///<remarks>
/// This method is only used by the fac and sfac methods and not the parser itself, it should
/// really leave this class since they have nothing to do with the parser.
///</remarks>
///<param name="a">the double value to check</param>
///<returns>true if the double value is an integer, false otherwise.</returns>
privatebool
isInteger(double a)
{
return ((a - (int)a) == 0.0);
}
///<summary>
/// Checks to see if the int value a can be considered to be even. </summary>
///<remarks>
/// This method is only used by the fac and sfac methods and not the parser itself, it should
/// really leave this class since they have nothing to do with the parser.
///</remarks>
///<param name="a">the int value to check</param>
///<returns>true if the int value is even, false otherwise.</returns>
privatebool
isEven(int a)
{
return (isInteger(a / 2));
}
///<summary>
/// Checks to see if the character is a valid symbol for this parser.
///</summary>
///<param name="s">the character to check</param>
///<returns>true if the char is valid, false otherwise.</returns>
privatebool
isAllowedSym(char s)
{
return (s == ',' || s == '.' || s == ')' || s == '(' || s == '>' || s == '<' || s == '&' || s == '=' || s == '|');
}
///<summary>
/// Checks the String expression to see if the syntax is valid.
/// this method doesn't return anything, instead it throws an Exception
/// if the syntax is invalid.
///
/// Examples of invalid syntax can be non matching paranthesis, non valid symbols appearing
/// or a variable or operator name is invalid in the expression.
///</summary>
///<param name="exp">the string expression to check, infix notation.</param>
privatevoid
Syntax(String exp)
{
int i = 0, oplen = 0;
String op = null;
String nop = null;
if (!matchParant(exp))
{
thrownew System.Exception("Non matching paranthesis");
}
int l = exp.Length;
while (i < l)
{
try
{
if ((op = getOp(exp, i)) != null)
{
oplen = op.Length;
i += oplen;
nop = getOp(exp, i);
if (nop != null&& isTwoArgOp(nop) && !(nop.Equals("+") || nop.Equals("-")))
{
thrownew System.Exception("Syntax error near -> " + exp.Substring(i - oplen));
}
}
elseif (!isAlpha(exp[i]) && !isConstant(exp[i]) && !isAllowedSym(exp[i]))
{
thrownew System.Exception("Syntax error near -> " + exp.Substring(i));
}
else
{
i++;
}
}
catch (IndexOutOfRangeException)
{
i++;
}
}
return;
}
///<summary>
/// Inserts the multiplication operator where needed.
/// This method adds limited juxtapositioning support.
///</summary>
///<remarks>
/// Juxtaposition is supported in these type cases:
///
/// case: variable jp one-arg-op , xcos(x)
/// case: const jp variable or one-arg-op, 2x, 2tan(x)
/// case: "const jp ( expr )" , 2(3+x)
/// case: ( expr ) jp variable or one-arg-op , (2-x)x , (2-x)sin(x)
/// case: var jp ( expr ) , x(x+1) , x(1-sin(x))
///
/// Note that this also puts extra limitations on variable names, they cannot
/// contain digits within them or at the beginning, only at the end.
///</remarks>
///<param name="exp">the infix string expression to process</param>
///<returns>the processed infix expression</returns>
privateString
putMult(String exp)
{
int i = 0, p = 0;
String tmp = null;
StringBuilder str = newStringBuilder(exp);
int l = exp.Length;
while (i < l)
{
try
{
if ((tmp = getOp(exp, i)) != null&& !isTwoArgOp(tmp) && isAlpha(exp[i - 1]))
{
// case: variable jp one-arg-op , xcos(x)
str.Insert(i + p, "*");
p++;
}
elseif (isAlpha(exp[i]) && isConstant(exp[i - 1])
&& (tmp == null || !tmp.Equals("log"))) // tmp was set by previous test
{
// case: const jp variable or one-arg-op, 2x, 2tan(x)
// note that "log" is treated specially
str.Insert(i + p, "*");
p++;
}
elseif (exp[i] == '('&& isConstant(exp[i - 1]))
{
// case: "const jp ( expr )" , 2(3+x)
str.Insert(i + p, "*");
p++;
}
elseif (isAlpha(exp[i]) && exp[i - 1] == ')'
&& (tmp == null || !tmp.Equals("log"))) // tmp was set by previous test
{
// case: ( expr ) jp variable or one-arg-op , (2-x)x , (2-x)sin(x)
str.Insert(i + p, "*");
p++;
}
elseif (exp[i] == '('&& exp[i - 1] == ')')
{
// case: ( expr ) jp ( expr ) , (2-x)(x+1) , sin(x)(2-x)
str.Insert(i + p, "*");
p++;
}
elseif (exp[i] == '('&& isAlpha(exp[i - 1]) && backTrack(exp.Substring(0, i)) == null)
{
// case: var jp ( expr ) , x(x+1) , x(1-sin(x))
str.Insert(i + p, "*");
p++;
}
}
catch { }
if (tmp != null)
{
i += tmp.Length;
}
else
{
i++;
}
tmp = null;
}
return str.ToString();
}
///<summary>
/// Adds support for "scientific notation" by replacing the E operator with *10^
///</summary>
///<remarks>
/// For example the value 1E-3 would be changed to 1*10^-3 which the parser will treat
/// as a normal expression.
///</remarks>
///<param name="exp">the infix string expression to process</param>
///<returns>the processed infix expression</returns>
privateString
parseE(String exp)
{
int i, p, len;
StringBuilder newstr = newStringBuilder(exp);
i = p = 0;
len = exp.Length;
while (i < len)
{
try
{
if (exp[i] == 'e'&&Char.IsDigit(exp[i - 1]))
{
if (Char.IsDigit(exp[i + 1]) || ((exp[i + 1] == '-' || exp[i + 1] == '+') &&Char.IsDigit(exp[i + 2])))
{
// replace the 'e'
newstr[i + p] = '*';
// insert the rest
newstr.Insert(i + p + 1, "10^");
p = p + 3; // buffer growed by 3 chars
}
}
}
catch { }
i++;
}
return newstr.ToString();
}
///<summary>
/// Parses out spaces from a string
///</summary>
///<param name="str">The string to process</param>
///<returns>A copy of the string stripped of all spaces</returns>
privateString
skipSpaces(String str)
{
int i = 0;
int len = str.Length;
StringBuilder nstr = newStringBuilder(len);
while (i < len)
{
if (str[i] != ' ')
{
nstr.Append(str[i]);
}
i++;
}
return nstr.ToString();
}
///<summary>
/// Matches an opening left paranthesis.
///</summary>
///<param name="exp">the string to search in</param>
///<param name="index">the index of the opening left paranthesis</param>
///<returns>the index of the matching closing right paranthesis</returns>
privateint
match(String exp, int index)
{
int len = exp.Length;
int i = index;
int count = 0;
while (i < len)
{
if (exp[i] == '(')
{
count++;
}
elseif (exp[i] == ')')
{
count--;
}
if (count == 0) return i;
i++;
}
return index;
}
///<summary>
/// Parses out an operator from an infix string expression.
///</summary>
///<param name="exp">the infix string expression to look in</param>
///<param name="index">the index to start searching from</param>
///<returns>the operator if any or null.</returns>
privateString
getOp(String exp, int index)
{
String tmp;
int i = 0;
int len = exp.Length;
for (i = 0; i < maxoplength; i++)
{
if (index >= 0 && (index + maxoplength - i) <= len)
{
tmp = exp.Substring(index, maxoplength - i);
if (isOperator(tmp))
{
return (tmp);
}
}
}
returnnull;
}
///<summary>
/// Parses an infix String expression and creates a parse tree of Node's.
///</summary>
///<remarks>
/// This is the heart of the parser, it takes a normal expression and creates
/// a datastructure we can easily recurse when evaluating.
///
/// The datastructure is then evaluated by the toValue method.
///</remarks>
///<param name="exp">the infix string expression to process</param>
///<returns>A tree datastructure of Node objects representing the expression</returns>
privateNode
parse(String exp)
{
int i, ma, len;
String farg, sarg, fop;
Node tree = null;
farg = sarg = fop = "";
ma = i = 0;
len = exp.Length;
if (len == 0)
{
thrownew System.Exception("Wrong number of arguments to operator");
}
elseif (exp[0] == '('&& ((ma = match(exp, 0)) == (len - 1)))
{
return (parse(exp.Substring(1, ma - 1)));
}
elseif (isVariable(exp))
{