计算器【难度:5级】:
答案1:
using NUnit.Framework;
[TestFixture]
public class UnitTest
{
public Evaluator Evaluator {
get; set; } = new Evaluator();
[Test]
[TestCase("12*-1", ExpectedResult = -12)]
[TestCase("12* 123/-(-5 + 2)", ExpectedResult = 492)]
[TestCase("((80 - (19)))", ExpectedResult = 61)]
[TestCase("(1 - 2) + -(-(-(-4)))", ExpectedResult = 3)]
[TestCase("1 - -(-(-(-4)))", ExpectedResult = -3)]
[TestCase("12* 123/(-5 + 2)", ExpectedResult = -492)]
[TestCase("(123.45*(678.90 / (-2.5+ 11.5)-(((80 -(19))) *33.25)) / 20) - (123.45*(678.90 / (-2.5+ 11.5)-(((80 -(19))) *33.25)) / 20) + (13 - 2)/ -(-11) ", ExpectedResult = 1)]
[TestCase("1+1", ExpectedResult = 2)]
[TestCase("1 - 1", ExpectedResult = 0)]
[TestCase("1* 1", ExpectedResult = 1)]
[TestCase("1 /1", ExpectedResult = 1)]
[TestCase("-123", ExpectedResult = -123)]
[TestCase("123", ExpectedResult = 123)]
[TestCase("2 /2+3 * 4.75- -6", ExpectedResult = 21.25)]
[TestCase("12* 123", ExpectedResult = 1476)]
[TestCase("12 * -123", ExpectedResult = -1476)]
[TestCase("2 / (2 + 3) * 4.33 - -6", ExpectedResult = 7.732)]
[TestCase("((2.33 / (2.9+3.5)*4) - -6)", ExpectedResult = 7.45625)]
[TestCase("123.45*(678.90 / (-2.5+ 11.5)-(80 -19) *33.25) / 20 + 11", ExpectedResult = -12042.760875)]
public double TestEvaluation(string expression)
{
return Evaluator.Evaluate(expression);
}
}
答案2:
using System;
using System.Data;
public class Evaluator
{
public double Evaluate(string s) => Math.Round(Convert.ToDouble(new DataTable().Compute(s, String.Empty)), 6);
}
答案3:
using System;
using System.Collections.Generic;
using System.Linq;
public class Evaluator
{
public double Evaluate(string expression)
{
expression = ReplaceOperators(expression);
return IsSimpleExpression(expression)
? ParseSimpleExpression(expression)
: ParseComplexExpression(expression);
}
private bool IsSimpleExpression(string expression)
{
double res;
return double.TryParse(expression, out res);
}
private double ParseSimpleExpression(string expression)
{
return double.Parse(expression);
}
private double ParseComplexExpression(string expression)
{
List<object> items = GetSplittedExpression(expression);
items = GetPolishNotatation(items);
return GetResult(items);
}
private double GetResult(List<object> items)
{
Stack<double> operands = new Stack<double>();
foreach (object item in items)
{
if (item is double)
{
operands.Push((double)item);
}
else
{
double op2 = operands.Pop();
double op1 = operands.Pop();
double res = GetResult(op1, op2, (char)item);
operands.Push(res);
}
}
return operands.Pop();
}
private double GetResult(double op1, double op2, char operation)
{
Func<double, double, double> func = GetFunc(operation);
return func(op1, op2);
}
private Func<double, double, double> GetFunc(char operation)
{
switch (operation)
{
case '+':
return (a, b) => a + b;
case '-':
return (a, b) => a - b;
case '*':
return (a, b) => a * b;
case '/':
return (a, b) => a / b;
default:
return null;
}
}
private List<object> GetPolishNotatation(List<object> items)
{
Queue<object> queue = new Queue<object>();
Stack<char> stack = new Stack<char>();
foreach (object item in items)
{
if (item is double)
{
queue.Enqueue(item);
}
else if (IsOperator((char)item))
{
char c = (char)item;
while (stack.Count > 0 && (GetPrecendence(stack.Peek()) > GetPrecendence(c)
|| (GetPrecendence(stack.Peek()) == GetPrecendence(c) && GetAssociativity(c) == "left"))
&& (stack.Peek() != '('))
{
queue.Enqueue(stack.Po