怎样做计算器可以做两个以上的操作 [英] How do make calculator that can do more than two operation

查看:69
本文介绍了怎样做计算器可以做两个以上的操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用c#语言在windows商店中制作计算器,但是我有一个问题,计算器可以一次做两个操作,例如:1 + 2,3 * 5。我想制作一次可以做多次操作的计算器,例如:1 + 4 + 6 + 7,6 / 3 * 3.



这里是代码:

I want to make calculator in windows store with c# language, But i have a problem, the calculator just can do two operation at once, for example: 1+2, 3*5. I want to make calculator that can do many operation at once, for example: 1+4+6+7, 6/3*3.

And here is the code:

public sealed partial class MainPage : Page
    {
        string op1;
        string op2;
        string op;
        bool first = true;
        bool evaluated = false;

        public MainPage()
        {
            this.InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (!evaluated)
            {
                Button button = (sender) as Button;
                string val = button.Content.ToString();

                switch (val)
                {
                    // values setting
                    case "1":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case "2":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case "3":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case "4":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case "5":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case "6":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case "7":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case "8":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case "9":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case "0":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;
                    case ".":
                        if (first) { op1 = op1 + val; FinalResult.Text = op1; } else { op2 = op2 + val; FinalResult.Text = op2; };
                        break;

                    // operators selection
                    case "+":
                        if (first) { first = false; } else { OperatorLocked(Convert.ToChar(val)); }
                        Expression.Text = op1 + " " + val;
                        FinalResult.Text = "0";
                        op = val;
                        break;
                    case "-":
                        if (first) { first = false; } else { OperatorLocked(Convert.ToChar(val)); }
                        Expression.Text = op1 + " " + val;
                        FinalResult.Text = "0";
                        op = val;
                        break;
                    case "*":
                        if (first) { first = false; } else { OperatorLocked(Convert.ToChar(val)); }
                        Expression.Text = op1 + " " + val;
                        FinalResult.Text = "0";
                        op = val;
                        break;
                    case "/":
                        if (first) { first = false; } else { OperatorLocked(Convert.ToChar(val)); }
                        Expression.Text = op1 + " " + val;
                        FinalResult.Text = "0";
                        op = val;
                        break;
                    case "%":
                        if (first)
                        {
                            new MessageDialog("Please select a statement of which you want to get the percentage.").ShowAsync();
                        }
                        else
                        {
                            if (op == "/")
                            {
                                // get percentage
                                FinalResult.Text = ((Convert.ToDouble(op1) / Convert.ToDouble(op2)) * 100).ToString();

                                op1 = "";
                                op2 = "";
                                op = "";
                                evaluated = true;
                            }
                            else
                            {
                                new MessageDialog("Only percentage is allowed.\n\nFor instance, Only division operator is allowed. value1 / value 2 and then press % to get their percentage.").ShowAsync();
                            }
                        }
                        break;
                    case "←":
                        if (first)
                        {
                            if (op1 != null && op1.Length > 0)
                            {
                                op1 = op1.Substring(0, op1.Length - 1);
                                FinalResult.Text = op1;
                            }
                            else
                            {
                                FinalResult.Text = "0";
                            }
                        }
                        else
                        {
                            if (op2 != null && op2.Length > 0)
                            {
                                op2 = op2.Substring(0, op2.Length - 1);
                                FinalResult.Text = op2;
                            }
                            else
                            {
                                FinalResult.Text = "0";
                            }
                        }
                        break;
                    case "=":
                        switch (op)
                        {
                            default:
                                if (!first)
                                {
                                    Evaluate(Convert.ToDouble(op1), Convert.ToDouble(op2), op);
                                    op1 = "";
                                    op2 = "";
                                    op = "";
                                    evaluated = true;
                                }
                                else
                                {
                                    new MessageDialog("Two operands must be selected and an operator must be selected, before you can evaluate them.").ShowAsync();
                                }
                                break;
                        }
                        break;
                }
            }
            else
            {
                FinalResult.Text = "0";
                Expression.Text = "";
                evaluated = false;

                Button_Click(sender, e);
            }
        }

        private void Evaluate(double op1, double op2, string op)
        {
            // Evaluate
            switch (op)
            {
                case "+":
                    FinalResult.Text = (op1 + op2).ToString();
                    Expression.Text = op1 + " + " + op2 + " =";
                    break;
                case "-":
                    FinalResult.Text = (op1 - op2).ToString();
                    Expression.Text = op1 + " - " + op2 + " =";
                    break;
                case "*":
                    FinalResult.Text = (op1 * op2).ToString();
                    Expression.Text = op1 + " x " + op2 + " =";
                    break;
                case "/":
                    FinalResult.Text = (op1 / op2).ToString();
                    Expression.Text = op1 + " / " + op2 + " =";
                    break;
            }
        }

        private void OperatorLocked(char op)
        {
            new MessageDialog(op.ToString() + " is currently not available. \n\nYou can only select two operands currently.");
        }
    }
}





任何人都可以帮我制作可以做多次操作的计算器一次,例如:1 + 4 + 6 + 7,6 / 3 * 3?



Can anyone help me to make calculator that can do many operation at once, for example: 1+4+6+7, 6/3*3?

推荐答案

有很好的工作中缀计算器示例,以及良好的解决方案在CodeProject上解析复杂字符串并生成可执行C#代码的任务;我建议你搜索这些文章并阅读它们以获得想法:[ ^ ]。



要制作真正有效的中缀计算器,您需要实施运算符优先级的规则,以及使用括号来覆盖运算符优先级。如果你制作了一个后期修复计算器(操作符之后的操作符,例如HP使用的),你就不会遇到这个问题。



double x = 3 - 2/5 // => 2.0因为标准运算符优先级首先调用除法



double y =(3 - 2)/ 5 // => 0.5因为括号强制首先评估减法



对于中缀计算,很可能你会想要使用'Stack,我建议你使用两个'Stack对象:一个用于操作数,一个用于操作符。



所以,你的表达式1 + 4 + 6 + 7被解析为:



operandStack 7 6 4 1 //从上到下订单

operatorStack + + + //从上到下订单



执行序列从操作符堆栈的顶部开始,从操作数堆栈中拉出两个值,然后添加它们,依此类推。



但是对于6/3 * 3,你不能简单地创建这样的堆栈:



operandStack 3 3 6 //从上到下的顺序

operatorStack * / //从上到下的顺序



因为先执行乘法会违反乘法和除法等于的标准中缀优先级规则优先级,第一个是encount首先执行从左到右的ered阅读。



我希望你能从这个简短的例子中看到如果你写一个中缀计算器你将需要处理的复杂性实现了大多数人期望的执行规则的优先级。
There are good examples of working infix calculators, and good solutions for the task of parsing a complex string and generating executable C# code, here on CodeProject; I suggest you search for those articles and read them to get ideas: [^].

To make an infix calculator that really "works" you are going to need to implement the rules for operator precedence, and the use of parentheses to over-ride operator precedence. If you make a post-fix calculator (operators after operands, as used by HP, for example), you will not have this problem.

double x = 3 - 2 / 5 // => 2.0 because standard operator precedence invokes division first

double y = (3 - 2) / 5 // => 0.5 because the parentheses force the subtraction to be evaluated first

For infix calculation, most likely you will want to use a 'Stack, and I suggest you use two 'Stack objects: one for the operands, one for the operators.

So, your expression "1+4+6+7" gets parsed into:

operandStack 7 6 4 1 // top to bottom order
operatorStack + + + // top to bottom order

And the execution sequence starts at the top of the operator stack, pulling out two values from the operand stack, and adding them, and so forth.

For "6/3*3" however, you can't just simply create the stacks like this:

operandStack 3 3 6 // top to bottom order
operatorStack * / // top to bottom order

Because executing multiply first will violate the standard infix priority rule that multiply and divide have equal priority, and the first one encountered reading left to right is executed first.

I hope you can see from this brief example the complexity of what you will need to deal with if you write an infix calculator that implements priority of execution rules most people expect.


这篇关于怎样做计算器可以做两个以上的操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆