-1

Well this questions is probably gonna be closed before I get an answer... I am trying to program a very simple calculator and this works flawlessly:

private void button1_Click(object sender, EventArgs e)
        {
            string[] input = rtbInput.Text.Split(' ');
            rtbInput.Text += " = " + CalculateNumber(input).ToString();
        }

long CalculateNumber(string[] input)
        {
            long curValue = 0;
            curValue = long.Parse(input[0]);
            //LOOK FOR PARENTHASIS, LAST INDEX, SEARCH FROM THERE UNTIL FIRST INDEX, RUN THIS AGAIN FOR THAT.
            //THEN REPLACE "5 + (3 + 3)" with 5 + 6. So calculate 3 + 3 = 6 and replace ( until ) with answer.
            if (rtbInput.Text.Contains("(") && rtbInput.Text.Contains(")"))
            {
                int c = 0;
                int startNum;
                int len;
                string s = "No";
            }

            int i = 0;
            while (i < (input.Length - 1))
            {
                switch (input[i])
                {
                    case "+":
                        curValue += long.Parse(input[i + 1]);
                        break;
                    case "-":
                        curValue -= long.Parse(input[i + 1]);
                        break;
                    case "*":
                        curValue = curValue * long.Parse(input[i + 1]);
                        break;
                    case "/":
                        curValue = curValue / long.Parse(input[i + 1]);
                        break;
                }
                i++;
            }

            return curValue;
        }

this works superbly. But when trying to add capability to calculate Parenthasis "(3 * 3) = 9" and i implement this code:

long CalculateNumber(string[] input)
        {
            long curValue = 0;
            curValue = long.Parse(input[0]);
            //LOOK FOR PARENTHASIS, LAST INDEX, SEARCH FROM THERE UNTIL FIRST INDEX, RUN THIS AGAIN FOR THAT.
            //THEN REPLACE "5 + (3 + 3)" with 5 + 6. So calculate 3 + 3 = 6 and replace ( until ) with answer.
            if (rtbInput.Text.Contains("(") && rtbInput.Text.Contains(")"))
            {
                int c = 0;
                int startNum;
                int len;
                string s = "No";
                //while there are still parenthasis in the input, do this
                if (c < rtbInput.Text.Split('(').Count() - 1)       //REPLACE WITH WHILE
                {
                    startNum = rtbInput.Text.LastIndexOf('(') + 1;
                    len = rtbInput.Text.IndexOf(')', startNum);// - startNum;
                    s = rtbInput.Text.Substring(startNum, len);
                    this.Name = s;
                    //NOW REPLACE THIS WITH THE RETURN OF CalculateParenthasis.Split(' ')
                    rtbInput.Text = rtbInput.Text.Replace("(" + s + ")", CalculateParenthasis(s.Split(' ')).ToString());
                }

long CalculateParenthasis(string[] input)
        {
            long curValue = 0;
            curValue = long.Parse(input[0]);
            button1.Text += curValue.ToString();
            int i = 0;
            while (i < (input.Length - 1))
            {
                switch (input[i])
                {
                    case "+":
                        curValue += long.Parse(input[i + 1]);
                        break;
                    case "-":
                        curValue -= long.Parse(input[i + 1]);
                        break;
                    case "*":
                        curValue = curValue * long.Parse(input[i + 1]);
                        break;
                    case "/":
                        curValue = curValue / long.Parse(input[i + 1]);
                        break;
                }
                i++;
            }

            return curValue;
        }

As you can see the CalculateParenthasis() function works exactly the same as CalculateNumber() but takes the number between the parenthasis, but this errors at the switch statement saying the input string was the wrong format? WTH? I barely don't know how to even ask this question, seems like something tiny and easy being wrong but I just can't see it.

Falconeer
  • 21
  • 4
  • 6
    A good opportunity to learn how to use the debugger. When the error occurs, inspect `input[i + 1]` and see if it is what you expect it to be. – Klaus Gütter Jan 18 '21 at 09:38
  • Another hint: _"this questions is probably gonna be closed before I get an answer"_ -- if you know before you post that your question is of low quality and is likely to be closed **then don't post that version of the question**. Stack Overflow offers plenty of good advice about how to present your question in a clear, answerable way, as well as what's expected from question authors _before_ they post. See e.g. [mcve] and [ask]. – Peter Duniho Jan 19 '21 at 08:01

1 Answers1

-1

Based on my test, I reproduced the problem you meet.

However, I find it is very hard for us to complete it because of its complexity.

Therefore, I recommend that you use Reverse Poland algorithm to make the calculator.

I make a code example to make it and you can refer to it.

Code:

public class Example
    {
        public static Stack<string> operStack = new Stack<string>();
        public static Stack<string> numStack = new Stack<string>();
        static bool IsNumber(string s)
        {
            return Regex.IsMatch(s, @"\d+");
        }

        static bool IsSiZe(string s)
        {
            string ts = "+-*/";
            return ts.IndexOf(s) > -1;
        }

        static int Level(string s)
        {
            int i = 0;
            switch (s)
            {
                case ",":
                    i = 0;
                    break;
                case "(":
                case ")":
                case "#":
                    i = 1;
                    break;
                case "+":
                case "-":
                    i = 2;
                    break;
                case "*":
                case "/":
                    i = 3;
                    break;
            }
            return i;
        }

        public static void Calc(Stack<string> numStack, Stack<string> operStack)
        {
            int rightnum = int.Parse(numStack.Pop());
            int leftnum = int.Parse(numStack.Pop());
            string oper = operStack.Pop();
            switch (oper)
            {
                case "+":
                    numStack.Push((leftnum + rightnum).ToString());
                    break;
                case "-":
                    numStack.Push((leftnum - rightnum).ToString());
                    break;
                case "*":
                    numStack.Push((leftnum * rightnum).ToString());
                    break;
                case "/":
                    numStack.Push((leftnum / rightnum).ToString());
                    break;
            }
       
        }

        public static void ToNiBoLan(string exp)
        {

            operStack.Push("#");  //Push into the stack  for comparsion

            string token = "";
            for (int i = 0; i < exp.Length; i++)
            {
                if (IsNumber(exp[i].ToString()))  //If it is number
                {
                    token += exp[i].ToString();
                }
                else if (exp[i].ToString() == "(")   
                {
                    operStack.Push(exp[i].ToString());
                    if (IsNumber(token))
                        numStack.Push(token);
                    token = "";
                }
                else if (IsSiZe(exp[i].ToString()))
                {
                    if (IsNumber(token))
                        numStack.Push(token);
                    token = "";
                    int item = Level(exp[i].ToString()).CompareTo(Level(operStack.Peek()));  //Comparison operator precedence
                    if (item > 0)  //If the priority is higher than the top of the stack, the operator is pushed onto the stack
                    {
                        operStack.Push(exp[i].ToString());
                    }
                    else   //If the operator is less than or equal to the top of the stack, calculate and push the operator onto the stack
                    {

                        Calc(numStack, operStack);

                        operStack.Push(exp[i].ToString());
                    }

                }
                else if (exp[i].ToString() == ")")  
                {
                    if (IsNumber(token))
                        numStack.Push(token);
                    token = "";
                    while (operStack.Peek() != "(")
                    {
                        Calc(numStack, operStack);
                    }
                    token = numStack.Pop();  //Take out the numbers for the next calculation
                    operStack.Pop();  //Eligible left parenthesis popped

                }
                else  //End of traversal
                {
                    if (IsNumber(token))
                        numStack.Push(token);
                    token = "";
                    while (numStack.Count > 1)
                    {
                        Calc(numStack, operStack);
                    }
                }
            }
        }

    }

Use it in winforms:

  private void button1_Click(object sender, EventArgs e)
        {
            //For comparison, add "#" at the end of the expression
            string text = richTextBox1.Text.Trim() + "#";
            Example.ToNiBoLan(text);
            richTextBox1.Text = Example.numStack.Pop().ToString();
        }

Besides, you can refer to the link Reverse polish notation C# don't work correctly.

Jack J Jun
  • 5,633
  • 1
  • 9
  • 27