现代软件工程 第一章 概论 第1题——邓琨

题目要求:

第一步: 像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 “软件”, 分别满足下面的各种需求。下面这些需求都可以用命令行参数的形式来指定:

a) 除了整数以外,还要支持真分数的四则运算。 (例如:  1/6 + 1/8 = 7/24)

b) 让程序能接受用户输入答案,并判定对错。 最后给出总共 对/错 的数量。

c) 逐步扩展功能和可以支持的表达式类型,最后希望能支持下面类型的题目 (最多 10 个运算符,括号的数量不限制):
         25 - 3 * 4 - 2 / 2 + 89 = ?
         1/2 + 1/3 - 1/4 = ? 
        (5 - 4 ) * (3 +28) =?

 d) 一次可以批量出 100 道以上的题目,保存在文本文件中, 并且保证题目不能重复,(1+2) 和 (2+1) 是重复的题目。 怎么保证题目不重复呢,请看详细题目要求

和同学们比较一下各自程序的功能、性能、实现方法的异同等等。

如何对一个表达式求值? 参考资料:

  http://hczhcz.github.io/2014/02/27/shunting-yard-algorithm.html

  https://en.wikipedia.org/wiki/Shunting-yard_algorithm

 鉴于该问题的难度与工作量,我将该问题拆分成3个小阶段进行实现:

1:复合四则运算的求值

2:随机生成复合四则运算

3:增加对真分数和假分数的支持

  分析:1.对于复合四则运算的求值,可以根据堆栈的特性,利用算数符合的优先级比较,对复合四则运算求值,详细的算法过程将在下文进行介绍。

     2.随机生成复合四则运算是本题目的一个难点,在进行思考过后,我觉得可以采用多次随机过程,生成四则运算表达式。第一次,随机参与计算的数字个数,第二次,随机数字的数值,第三次,随机数字间的四则运算符,第四次,随机括号的添加。注意,由于可能存在除0运算,所以要对这种错误情况进行排除。由于第三次和第四次随机过程的特殊性,即使在第三步出现例如:3 / 0  + 1 的运算表达式,但是如果第四次随机过程在算式 0 + 1 外生成括号,造成 3 / ( 0 + 1 )的结果,这种算式也是正确的。因此,不能保证在随机生成复合四则运算的过程中进行除0的判断。

      对于这个问题,我的个人思路是:在生成每一个复合四则运算后,进行复合运算求值,并在算法每一次求值过程中就行判断,如果出现除0错误,就抛出异常,标记当前生成的四则运算式子非法,进行重新生成。虽然除0的情况很多,这样会浪费大量的时间进行判断,但是由于问题的时间复杂度和空间复杂度都非常小,可以忽略不计。

     3.在增加真分数和假分数运算时候,只需要对每一种四则运算进行一次条件判断,因此无较大的难度。

一、复合四则运算的求值

表达式求值的算法:

  我采用的是“算符优先法”,在表达式中,优先级的顺序是:

  1、括号的优先级最高,对括号内的各种运算符有:先乘除,后加减,同级运算从做至右

  2、先括号内,后括号外,多层括号,由内向外。

  操作数可以是常量、变量、常数。
  运算符有算术运算符、关系运算符、逻辑运算符。
  界符包括左右括号算式结束符。
  运算符和界符统称为“算符”。

  

在算符集中,在每一个运算步,相邻的算符c1 和c2之间的关系是如下三种情况(c1出现在c2之前):
c1<c2,c1的优先级低于c2
c1=c2,c1的优先级等于c2
c1>c2,c1的优先级大于c2

下图描述的算符的优先级:

为实现算符优先算法,在这里用了两个工作栈。一个存放算符OPTR,另一个存放数据OPND。算法思想是:

(1)首先置数据栈为空栈,表达式起始符“#”为算符栈的栈底元素
(2)自左向右扫描表达式,读到操作数进OPND栈,读到运算符,则和OPTR栈顶元素比较(栈顶元素为c1,读到的算符为c2);
  若c1<c2,则c2进栈继续扫描后面表达式;
  若c1=c2,则(“=”),即括号内运算结束,将c1出栈,并且c2放弃,继并在操作数栈扫描后面表达式;
  若c1>c2,则将c1出栈,并在操作数栈取出两个元素a和b按c1做运算,运算结果进OPND.
  重复直到表达式求值完毕。

例如:表达式3*(7-2),求值过程如下表:

  步骤     OPTR栈     OPND栈     输入字符     主要操作  
1 #   3*(7-2)# PUSH(OPND,‘3‘)
2 # 3 *(7-2)# PUSH(OPTR,‘*‘)
3 #* 3 (7-2)# PUSH(OPTR,‘(‘)
4 #*( 3 7-2)# PUSH(OPND,‘7‘)
5 #*( 3 7 -2)# PUSH(OPTR,‘-‘)
6 #*(- 3 7  2)# PUSH(OPND,‘2‘)
7 #*( 3 7 2 )# operate(7-2)
8 #*( 3 5  )# pop()
9 #* 15 # operate(3*5)
10 # 15 # PUSH(OPTR,‘#‘)

为使两个算符比较方便,给算符设置优先级,如下表,其中c1为栈内元素,c2为栈外元素:

算符比较算法:  

char Precede(char c1,char c2)
{int c_temp1,c_temp2;
switch(c1)
{ case ‘*’:
case ‘/’:c_temp1=4;break;
case ‘+’:
case ‘-’:c_temp1=2;break;
case ‘(’:c_temp1=0;break;
case ‘)’:c_temp1=5;break;
case ‘#’:c_temp1=-1;
}
switch(c2)
{ case ‘*’:
case ‘/’:c_temp2=3;break;
case ‘+’:
case ‘-’:c_temp2=1;break;
case ‘(’:c_temp2=5;break;
case ‘)’:c_temp2=0;break;
case ‘#’:c_temp2=-1;}
if(c_temp1<c_temp2) return(‘<‘);
if(c_temp1=c_temp2) return(‘=‘);
if(c_temp1>c_temp2) return(‘>‘);
}
int express()
{
Initstack(OPTR);Push(OPTR,’#’);
InitStack(OPND);
w=getchar();
while(w!=‘#’||GetTop(OPTR)!=‘#’)
   {if(!In(w,OP)){Push(OPND,w);w=getchar();}
else        //OP是操作符集合
switch(Precede(GetTop(OPTR),w))
{case ‘<‘:   Push(OPTR,w);w=getchar();break;
case ‘=‘:   Pop(OPTR);w=getchar();break;
case ‘>‘:   op=Pop(OPTR);b=Pop(OPND);a=Pop(OPND);
push(OPND,Operate(a,op,b));break;}}
return(Getop(OPND)
);

算符优先算法求表达式值:

OperandType EvaluateExpression() {
    InitStack (OPTR); Push ( OPTR,’#’);
    InitStack (OPND); c=getchar();
    while (c!=‘#’|| GetTop(OPTR)!=‘#’) {
        if(!In(c,OP)){Push(OPND,c);
            c=getchar();}
        else
            switch(Precede(GetTop(OPTR),c){
            case ‘<‘://栈顶元素优先权低
                Push(OPTR,c); c=getchar();
                break;
                        case ‘=‘://脱括号
                Pop(OPTR,x); c=getchar();
                break;
            case ‘>’://退栈并计算
                Pop(OPTR,theta);
                Pop(OPND,b); Pop(OPND,a);
                Push(OPND, Operate(a,theta,b));
                break;
            }//switch
    }//while
    return GetTop(OPND);
}//EvaluateExpression
            
时间: 2024-10-07 11:35:01

现代软件工程 第一章 概论 第1题——邓琨的相关文章

现代软件工程 第一章 概论 第9题——邓琨

我采访了一只开发了天津8890便民服务网站系统的团队. - 当时的项目有多少用户,给用户多少价值? 现在还有人用吗? 答:当时项目有近万用户,为天津市民提供便民服务平台,例如联系修理家电.水电气.咨询服务.中介.邮政服务等各种便民服务,集老百姓生活所需服务为一身,通过各种服务接口,统一为人们提供生生活服务.现在还有很多用户正在使用该系统,每天的访问量一直保持增长趋势. - 这个项目能否给我们团队继续开发,源代码/文档还有么? 答:这个项目可以进行二次开发,当时项目团队进行了缜密的版本控制管理与文

现代软件工程 第一章 概论 第4题——邓琨

我赞同dijkstra的看法.会一两种编程语言,会写贪吃蛇游戏,会写网站网页,这并不叫会写程序,只能说是管中窥豹,略见一斑.而软件工程是从宏观和微观两个角度教一个人怎么写程序.一是教怎么使用程序语言,怎么设计算法,怎么通过使用语句的组合构成一个可运行的程序:另一方面是怎么进行软件架构,怎么使用设计模式,怎么进行测试,怎么进行运行维护,怎么开发出一个健壮.安全.完善.可靠的软件或系统,它包含多个方面的软件开发技术. 在学校里有的同学算法和数据结构很擅长,例如参加ACM竞赛的同学,他们的编程能力比一

现代软件工程 第一章 概论 第11-15题(白文俊)

11.Software,  Software Engineering 等名词的来源,请问 “软件” 和 “软件工程” 这些词汇是如何出现的 - 何时.何地.何人 在看过给的链接原文之后我得出这样的结论: ”software”即“软件”这一名词的使用最早是在1953年8月由Richard R. Carhart发表的一篇工程性的文章中,收录在Rand公司的研究备忘录中. “software engineering”即“软件工程”这一名词的使用最早是在阿波罗11登月计划由著名的女程序员Margaret

现代软件工程 第一章 概论 第7题——张星星

综合多方面考虑,我认为,”中文编程”并不是一个”银弹”,并不能提高中国程序员的编程效率. 首先,中文编程指的是使用中文书写关键字,如类名.函数名.变量名.常量名等.对编程语言来说,语法关键字其实就是一个符号,和日常语言关系不大.不同的编程语言对应的关键字也不相同,所以中文编程对应的母语优势意义不大,记住几个外语关键字并不会降低开发效率. 另外,中文编程在输入上也没有优势,例如a = 1 和甲 等于 一:而且中文还存在编码问题,运行环境苛刻,使用中文编程要有一系列的支持,如windows中文api

现代软件工程 第一章概论习题第1题 李艳薇

实现自动出题功能: 程序并没有实现全部要求,后续将会继续改进. 实现结果: 程序代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <time.h> using namespace std; #define N 100 bool createProblem(){ int i,op,x; char st[100]; int dt[1

现代软件工程第一章 第十五题--刘莞姝

15:请看TED 的演讲, 谈谈你对压力的看法,以及怎么和别人合作, 帮助别人,把压力转化为动力,在互相帮助的环境中成长. 我相信大多数人都不会喜欢跟压力相处,但是在这样的社会环境下,压力是无法避免的,因此我们要学会与压力相处.与压力相处,并不是说一定要把压力变为动力,压力可以是动力的一部分,但绝对不会是动力的来源.压力可以是你做一件事的催化剂,但是不能成为你开始做一件事的主要原因.所谓学会与压力相处,就是要在压力过大时,想办法排解它:不要让压力给你带来过重的思想负担:必要的时候让压力成为你的“

邹欣老师的《构建之法》第一章“概论”学习笔记与自我随笔

刚读完了邹欣老师的<构建之法>第一章“概论”,四个字形容:酣畅淋漓. 概论将自己的一些模糊的认识清晰化,用准确的文字描述了出来,填补了脑海里的一些灰色地带. 总结一下:概论通俗地阐述了编程.软件.计算机科学.软件工程的联系与区别,简单说,编程是一项具体动作,软件是供人使用的产品,具体有很多种类型,而计算机科学是偏向理论研究,软件工程就像其他工程学一样,是在一定条件下合理配置资源达到生产软件的目的. 本人作为一名从小对编程.软件.计算机感兴趣的Nerd,虽然大学专业与此无关,但刚毕业时签了一份软

软件工程第一章精读——刘天乐 20194597

第一章 概论 1.1软件=程序+软件工程 “程序=数据结构+算法”——c语言实现二叉树遍历算法 程序对用户的需求 程序对数据进行操作——静态.动态 软件的构建的过程——合理的软件架构(Software Architecture).软件设计与实现(Software Design,Implementation and Debug) 软件企业=软件+商业模式 1.2软件工程是什么 1.2.1软件的特殊性:复杂性.不可见性.易变性.服从性.非连续性 1.2.2软件工程与计算机科学的关系 (1)计算机科学

软件工程—第一章

软件工程—第一章概述 软件的定义是计算机程序.规程以及运行计算机系统可能需要的相关文档和数据,软件开发存在的问题是由特性决定的,软件危机从爆发到至今依然没有消除. 软件工程以关注软件质量为目标,由过程.方法和工具三要素组成,软件质量与客户.用户.维护人员等提出的要求密切相关,当前面临的主要挑战有:遗留系统的问题.高可信软件开发的要求.软件开发方式的变化. SWEBOK的组成:软件需求.软件设计.软件构造.软件测试.软件维护.软件配置管理.软件工程管理.软件工程过程.软件工程工具与方法.软件质量.