我的计算器带有括号的优先运算

时间:2018-12-16 13:39:43

标签: c# .net

在我的计算器中,我想要带括号的操作优先级的概念。

我进行了单元测试以尝试解决该问题,但无法使其正常工作。

单元测试

[Test]
public void Parenthesis_Priority_Case()
{
    OperandBase operand = OperandFactory.Create("(1+2)*42");

    Assert.IsAssignableFrom<OperandMultiply>(operand);
    OperandMultiply multiply = (OperandMultiply)operand;
    AssertIsOperandValue(multiply.RightOperand, 42);
    AssertIsOperand<OperandAddition>(multiply.LeftOperand, 1, 2);
}

我的单元测试的输出结果

Expected: assignable from <CalculateLib.Operands.OperandMultiply>
But was:  <CalculateLib.Operands.OperandAddition>

    at
CalculateTest.OperandFactoryTests.When_Create_ 
Is_Called.Parenthesis_Priority_Case() in 
D:\GIT\Calculate\CalculateTest\OperandFactoryTests
\When_Create_Is_Called.cs:line 79

下面的代码是我的工厂:

public static class OperandFactory
{
    private static Regex parenthesisRegex = new Regex(@"\((?<content>.+)\)$", RegexOptions.Compiled);

    public static OperandBase Create(string input)
    {
        if (HasParenthesisToRemove(input))
        {
            return Create(GetOperationWithoutParenthesisString(input));
        }

        bool isValue = decimal.TryParse(input, out decimal outValue);
        if (isValue)
        {
            return new OperandValue
            {
                Value = outValue
            };
        }

        bool isAddition = input.Contains("+");
        if (isAddition)
        {
            string leftOperand = GetLeftOperandOfAdditionString(input);
            string rightOperand = GetRightOperandOfAdditionString(input);
            return new OperandAddition()
            {
                LeftOperand = Create(leftOperand),
                RightOperand = Create(rightOperand)
            };
        }

        bool isSubstract = input.Contains("-");
        if (isSubstract)
        {
            string leftOperand = GetLeftOperandOfSubstractString(input);
            string rightOperand = GetRightOperandOfSubstractString(input);
            return new OperandSubstract()
            {
                LeftOperand = Create(leftOperand),
                RightOperand = Create(rightOperand)
            };
        }

        bool isMultiply = input.Contains("*");
        if (isMultiply)
        {
            string leftOperand = GetLeftOperandOfMultiplyString(input);
            string rightOperand = GetRightOperandOfMultiplyString(input);
            return new OperandMultiply()
            {
                LeftOperand = Create(leftOperand),
                RightOperand = Create(rightOperand)
            };
        }

        bool isDivide = input.Contains("/");
        if (isDivide)
        {
            string leftOperand = GetLeftOperandOfDivideString(input);
            string rightOperand = GetRightOperandOfDivideString(input);
            return new OperandDivide()
            {
                LeftOperand = Create(leftOperand),
                RightOperand = Create(rightOperand)
            };
        }

        return null;
    }

    public static bool HasParenthesisToRemove(string input)
    {
        if (!IsStartAndEndWithParenthesis(input))
        {
            return false;
        }

        if (!HasValueInsideParenthesis(input))
        {
            return false;
        }

        string[] groups = GetGroups(input);

        return groups.Contains(input);
    }

    public static string[] GetGroups(string input)
    {
        const string pattern = @"(?=(\((?>[^()]+|(?<o>)\(|(?<-o>)\))*(?(o)(?!)|)\)))";
        IEnumerable<string> result = Regex.Matches(input, pattern).Cast<Match>().Select(x => x.Groups[1].Value);
        return result.ToArray();
    }

    private static bool HasValueInsideParenthesis(string input)
    {
        if (!parenthesisRegex.IsMatch(input))
        {
            return false;
        }

        return true;
    }

    private static bool IsStartAndEndWithParenthesis(string input)
    {
        if (!input.Contains("(") && !input.Contains(")"))
        {
            return false;
        }

        return true;
    }

    public static string GetLeftOperandOfDivideString(string input)
    {
        string[] inputString = input.Split('/');
        return inputString[0];
    }

    public static string GetRightOperandOfDivideString(string input)
    {
        return input.Substring(GetLeftOperandOfDivideString(input).Length + 1);
    }

    public static string GetLeftOperandOfMultiplyString(string input)
    {
        string[] inputString = input.Split('*');
        return inputString[0];
    }

    public static string GetRightOperandOfMultiplyString(string input)
    {
        return input.Substring(GetLeftOperandOfMultiplyString(input).Length + 1);
    }

    public static string GetLeftOperandOfSubstractString(string input)
    {
        string[] inputString = input.Split('-');
        return inputString[0];
    }

    public static string GetRightOperandOfSubstractString(string input)
    {
        return input.Substring(GetLeftOperandOfSubstractString(input).Length + 1);
    }

    public static string GetLeftOperandOfAdditionString(string input)
    {
        string[] inputString = input.Split('+');
        return inputString[0];
    }

    public static string GetRightOperandOfAdditionString(string input)
    {
        return input.Substring(GetLeftOperandOfAdditionString(input).Length + 1);
    }

    public static string GetOperationWithoutParenthesisString(string input)
    {
        var match = parenthesisRegex.Match(input);
        if (match.Success)
        {
            return match.Groups["content"].Value;
        }

        return null;
    }
}

我想知道您是否对此问题有任何想法或解决方案? 如果您希望有其他代码部分,请随时询问我

编辑

问题在于,优先顺序不佳的paretheses。我想知道问题出在哪里,因为我无法识别它。

0 个答案:

没有答案