代码改变世界

第二次作业_201731062533

2019-03-28 19:44  MarkarovZ  阅读(151)  评论(1编辑  收藏  举报
GIT地址  https://github.com/MarkarovZ
GIT用户名  MarkarovZ
学号后五位  62533
博客地址  https://www.cnblogs.com/MarkarovZ/
作业链接  https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass2/homework/2795

 

 

 

 

一.配置开发环境

  VS在刚入学的时候就装好了,截图是重新打开Visual Studio Installer截取的,在安装VS的时候没有遇到问题。

二.代码设计

  整个程序分成两个大模块:1.生成算式字符串2.计算算式的结果并验证该算式是否符合要求

1.

/// <summary>
        /// 生成算式
        /// </summary>
        /// <param name="num">算式数量</param>
        void FormulaGeneration(int num)
        {
            string formula = "";
            int n = 0;
            string str = "";
            double ans = 0;
            for (int i = 0; i < num; i++)
            {
                n = random.Next(2, 4);
                do
                {
                    str = FormulaCreation(n);
                    formula = str + "!";
                    ans = operate(formula);
                    if (ans % 1 == 0 && ans > 0 && flag == true)
                    {
                        break;
                    }
                } while (true);
                formula = str + "=" + operate(formula); ;
                formulas.Add(formula);
                
            }
        }
        /// <summary>
        /// 生成算式字符串
        /// </summary>
        /// <param name="n">运算符数量</param>
        /// <returns>算式字符串</returns>
        string FormulaCreation(int n)
        {
            int a, b, c, d, e;
            string x, y, z;
            switch (n)
            {
                case 2:
                    a = random.Next(0, 101);
                    b = random.Next(0, 101);
                    c = random.Next(0, 101);
                    d = random.Next(0, 4);
                    x = Formula(d);
                    d = random.Next(0, 4);
                    y = Formula(d);
                    return a + "" + x + "" + b + "" + y + "" + c;
                case 3:
                    a = random.Next(0, 101);
                    b = random.Next(0, 101);
                    c = random.Next(0, 101);
                    d = random.Next(0, 101);
                    e = random.Next(0, 4);
                    x = Formula(e);
                    e = random.Next(0, 4);
                    y = Formula(e);
                    e = random.Next(0, 4);
                    z = Formula(e);
                    return a + "" + x + "" + b + "" + y + "" + c + "" + z + "" + d;
            }
            return "";
        }
        /// <summary>
        /// 返回运算符
        /// </summary>
        /// <param name="n">运算符类型</param>
        /// <returns>运算符</returns>
        string Formula(int n)
        {
            switch(n)
            {
                case 0:
                    return "+";
                case 1:
                    return "-";
                case 2:
                    return "*";
                case 3:
                    return "/";
            }
            return "";
        }
生成算式字符串

2.

#region
        private bool judgenumber(string text)//判断是否为数字
        {
            try
            {
                int var1 = Convert.ToInt32(text);
                return true;
            }
            catch
            {
                return false;
            }
        }
        private bool judgeoperator(string text)//判断是否为运算符
        {
            if (text == "(" || text == ")" || text == "+" || text == "-" || text == "*" || text == "/")
            {
                return true;
            }
            else
                return false;
        }
        public object addition(object a, object b)//加法
        {
            Decimal d1 = Decimal.Parse(a.ToString());
            Decimal d2 = Decimal.Parse(b.ToString());
            return d2 + d1;
        }
        public object subduction(object a, object b)//减法
        {
            Decimal d1 = Decimal.Parse(a.ToString());
            Decimal d2 = Decimal.Parse(b.ToString());
            return d2 - d1;
        }
        public object multiplication(object a, object b)//乘法
        {
            Decimal d1 = Decimal.Parse(a.ToString());
            Decimal d2 = Decimal.Parse(b.ToString());
            return d2 * d1;
        }
        public object division(object a, object b)//除法
        {
            Decimal d1 = Decimal.Parse(a.ToString());
            Decimal d2 = Decimal.Parse(b.ToString());
            if(d2%d1!=0||d2<d1)
            {
                flag = false;
                return -10000;
            }
            else
            {
                flag = true;
                return d2 / d1;
            }

        }
        int judgelevel(string text)//判断优先级
        {
            if (text.Equals("("))
            {
                return 1;
            }
            else if (text.Equals(")") || text.Equals("") || text.Equals(""))
            {
                return 1;
            }
            else if (text.Equals("+") || text.Equals("-"))
            {
                return 2;
            }
            else if (text.Equals("*") || text.Equals("/"))
            {
                return 3;
            }
            else
                return 10;


        }
        int operator_dected(string types, string a, string b)//根据运算符的类型返回对应的值
        {
            if (types == "+")
            {
                return Convert.ToInt32(addition(a, b));
            }
            else if (types == "-")
            {
                return Convert.ToInt32(subduction(a, b));
            }
            else if (types == "*")
            {
                return Convert.ToInt32(multiplication(a, b));
            }
            else if (types == "/")
            {
                return Convert.ToInt32(division(a, b));
            }
            else
                return 999;
        }
        double operate(string Str)
        {
            stack_number.Clear();//清空栈
            stack_operator.Clear();
            str = Str + "!";//!为结束运算符
            int temp_count = 0;
            try
            {
                for (int i = 0; i < str.Length; i++)
                {
                    substr = str.Substring(i, 1);
                    if (judgenumber(substr))//如果是数字
                    {
                        if (temp_count == 0)
                        {
                            stack_number.Push(substr);
                        }
                        else
                            temp_count--;
                        if (judgenumber(str.Substring(i + 1, 1)))
                        {
                            string link1 = stack_number.Pop();
                            link1 += str.Substring(i + 1, 1);
                            stack_number.Push(link1);
                            temp_count++;
                        }
                    }
                    else if (judgeoperator(substr))
                    {
                        if (stack_operator.Count >= 1)
                        {
                            int new1 = judgelevel(substr);
                            int old1 = judgelevel(stack_operator.Peek());
                            if (old1 < new1 || substr == "(")//判断优先级
                            {
                                stack_operator.Push(substr); //将运算符插入栈中
                            }
                            else
                            {
                                if (substr == ")")
                                {
                                    for (; stack_operator.Count > 0; stack_operator.Pop())
                                    {
                                        if (stack_operator.Contains("(") && stack_operator.Peek() == "(")
                                        {
                                            stack_operator.Pop();
                                            break;
                                        }
                                        else
                                        {
                                            int temp1 = Convert.ToInt32(stack_number.Peek()); stack_number.Pop();
                                            int temp2 = Convert.ToInt32(stack_number.Peek()); stack_number.Pop();
                                            stack_number.Push(operator_dected(stack_operator.Peek(), temp1.ToString(), temp2.ToString()).ToString());
                                        }
                                    }
                                }
                                else
                                {
                                    for (; stack_operator.Count > 0 && stack_number.Count >= 2 && stack_operator.Peek() != "("; stack_operator.Pop())
                                    {
                                        string temp_a = substr;
                                        int new2 = judgelevel(temp_a);
                                        int old2 = judgelevel(stack_operator.Peek());
                                        if (old2 < new2 || substr == "(")//判断优先级
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            int temp3 = Convert.ToInt32(stack_number.Peek()); stack_number.Pop();
                                            int temp4 = Convert.ToInt32(stack_number.Peek()); stack_number.Pop();
                                            stack_number.Push(operator_dected(stack_operator.Peek(), temp3.ToString(), temp4.ToString()).ToString());
                                        }
                                    }
                                    stack_operator.Push(substr);
                                }
                            }
                        }
                        else
                        {
                            stack_operator.Push(substr);


                        }
                    }
                    else if (substr == "!")
                    {
                        for (; stack_operator.Count > 0 && stack_number.Count >= 2 && stack_operator.Peek() != "("; stack_operator.Pop())
                        {
                            int temp3 = Convert.ToInt32(stack_number.Peek()); stack_number.Pop();
                            int temp4 = Convert.ToInt32(stack_number.Peek()); stack_number.Pop();
                            stack_number.Push(operator_dected(stack_operator.Peek(), temp3.ToString(), temp4.ToString()).ToString());
                        }
                        return Convert.ToDouble(stack_number.Peek());
                    }
                    else
                    {
                        
                        break;
                    }
                }
            }
            catch
            {


            }
            return 0;
        }
        #endregion
四则运算栈

GITHUB

我是用的是带图形操作界面的githubDesktop,下图为从作业地址克隆后的我的github仓库的结果

该图为更改后,向仓库上传最新版本

下图为向原作者提供修改过的版本

项目测试:

1.运行结果:

2.单元测试:

性能测试:

在性能测试结果里,我发现程序大部分时间花费在了多余的函数调用上,如

for (int i = 0; i < num; i++)
            {
                n = random.Next(2, 4);
                do
                {
                    str = FormulaCreation(n);
                    formula = str + "!";
                    ans = operate(formula);
                    if (ans % 1 == 0 && ans > 0 && flag == true)
                    {
                        answers.Add(ans);
                        break;
                    }
                } while (true);
                formula = str + "=" + operate(formula); ;
                formulas.Add(formula);
                
            }
问题代码

此时为更改前,将

formula = str + "=" + operate(formula);

更改为

formula = str + "=" + ans;

即可减少n次operate函数的调用。

 

 

总结:

本次作业复习巩固了代码测试与性能优化的相关知识。