热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

第一次个人项目(2):拓展功能四则运算自动生成

需求分析:编写程序能自动生成100以内四则运算题目,运算符不多于10个,必须出现括号及分数。还需要不能出现负数(小学生不会做)࿰

   需求分析:编写程序能自动生成100以内四则运算题目,运算符不多于10个,必须出现括号及分数。还需要不能出现负数(小学生不会做),且问题不能重复。

     再看到题目之后觉得较为棘手,尤其是问题不能重复,一时不知道从哪下手,但是经过简单的分析,我认为只需要利用中缀表达的一定规律便可构造出符合要求的算式。首先在不考虑括号的情况下,中缀表达式在形式上都是一个数字后跟一个算符,最后是等号。若不算等号,那么在一个式中必然有n个数字和(n-1)个四则运算符。既然这样,我想首先通过随机数确定生成的算式中运算符的数量,然后再以此随机生成对应的数字,在生成数字时需有一部分数字是分数。在生成后我们可以按照数字、符号、数字、符号的顺序插入形成一个逻辑上正确的算式。

    在这基础上再考虑括号的加入,首先明确括号的使用方式,往往是在优先级高的算符前表示优先级低的算符要先进行计算时使用。例如1+2*3和(1+2)*3,所以我希望在生成了优先级较高的运算符如乘号、除号时,先检测在它之前的运算符,若优先级低于新加入的算符,则利用随机数确定是否在当前位置加入括号。

    在加入括号后,就不能盲目按照数字、算符的方式插入。要先判断插入的符号是否为括号,若为左括号则先插入括号在插入数字和一个运算符,若为右括号则在插入括号之后还需插入一个运算符。

    下面介绍具体实现,定义了表示数字的结构体,与上一篇中表示数字的方式大同小异,但没有加入符号的表示:

struct Number{int inte;//整数部分int deo;//分母int ele;//分子
};
char tmp[20];
char cha[20];

    字符型数组cha中存放随机生成的算符,下面是该程序的核心之一,生成数字和运算符:

1 void CreateNumber(int times){//根据times确定生成数字的数量
2 int iffrac;//根据随机数确定是否生成分数
3 for(int i &#61; 0; i<&#61;times;i&#43;&#43;){
4 iffrac &#61; rand()%4;
5 if(!iffrac){ //生成分数
6 num[i].deo &#61; rand()%98&#43;2;//控制数字大小
7 num[i].ele &#61; rand()%num[i].deo;
8 num[i].inte &#61; 0;//可加整数部分
9 }
10 else{
11 num[i].ele &#61; 0;
12 num[i].deo &#61; 1;
13 num[i].inte &#61; rand()%100&#43;1;//控制整数部分大小
14 }
15 }
16 }
17 void CreateChar(int times){//生成运算符号
18 int mode;
19 int i &#61; 0;
20 for(int j &#61; 0; j){
21 mode &#61; rand()%4;//根据随机数值生成相应的符号
22 switch(mode){
23 case 0:
24 cha[i] &#61; &#39;&#43;&#39;;break;
25 case 1:
26 cha[i] &#61; &#39;-&#39;;break;
27 case 2:
28 if((cha[i-1]&#61;&#61;&#39;&#43;&#39;)||(cha[i-1]&#61;&#61;&#39;-&#39;))//若乘号优先级高于前一个符号是否添加括号
29 if(!(rand()%2)){
30 cha[i] &#61; cha[i-1];
31 cha[i-1] &#61; &#39;(&#39;;
32 cha[i&#43;1] &#61; &#39;)&#39;;
33 i&#43;&#61;2;
34 }
35 cha[i] &#61; &#39;*&#39;;break;
36 case 3:
37 if((cha[i-1]&#61;&#61;&#39;&#43;&#39;)||(cha[i-1]&#61;&#61;&#39;-&#39;))//是否添加括号
38 if(!(rand()%2)){
39 cha[i] &#61; cha[i-1];
40 cha[i-1] &#61; &#39;(&#39;;
41 cha[i&#43;1] &#61; &#39;)&#39;;
42 i&#43;&#61;2;
43 }
44 cha[i] &#61; &#39;%&#39;;break;
45 default:break;
46 }
47 i&#43;&#43;;
48 }
49 cha[i]&#61;&#39;&#61;&#39;;//符号结尾用“&#61;”表示
50 }

生成数字和运算符

    大量使用随机数来确定是否生成分数&#xff0c;是否添加括号等行为。

    现在我们得到了一个随机的数字序列和一个随机但合乎逻辑的符号序列&#xff0c;现在只需要将它们按照顺序插入即可获得符合规则的算式&#xff1a;

1 void CreateQuestion(int quan,string &ans){//生成算式存放在ans中
2 int j;
3
4 CreateNumber(quan);
5 CreateChar(quan);
6 j &#61; 0;//指示算符
7 for(int p &#61; 0;p <&#61; quan;p&#43;&#43;){//显示算式
8 if(cha[j]&#61;&#61;&#39;(&#39;){//若有括号则显示括号
9 ans&#61;ans&#43;cha[j];
10 j&#43;&#43;;
11 }
12 DisplayNumber(p,ans);//显示数字
13 if(cha[j]&#61;&#61;&#39;)&#39;){//若有右括号则显示括号
14 ans&#61;ans&#43;cha[j];
15 j&#43;&#43;;
16 }
17 ans&#43;&#61;cha[j];
18
19 j&#43;&#43;;
20 }
21 }

生成算式

    这里为避免除号和分号的混淆&#xff0c;我用百分号"%"表示除号。生成的算式如下&#xff1a;

     这样来看&#xff0c;拓展功能基本实现了&#xff0c;还剩下判重和非负数。这里我就使用了一个比较笨的方法&#xff0c;在判重时我在构造好新的算式后利用上次得到的方法进行计算&#xff0c;算出答案后把当前答案与之前所有的算式答案进行比较&#xff0c;若有答案相同&#xff0c;则放弃新生成的算式&#xff0c;重新进行生成。答案不同的算式绝对不会重复的。同理&#xff0c;当计算得到的答案为负数时也重新生成。以下是生成全部算式的过程&#xff1a;

1 int q &#61; rand()%11&#43;10;//生成题目个数
2 freopen("question.txt","w",stdout);
3 for(int i &#61; 0; i){
4 do{
5 memset(num,11*sizeof(Number),0);//清空上次题目数字
6 memset(cha,20*sizeof(char),0);//清空上次题目算符
7 memset(tmp,20*sizeof(char),0);
8 question.clear();//清除本次生成题目
9 CreateQuestion(rand()%4&#43;1,question);//生成题目
10
11 ques &#61; question.c_str();
12 times &#61; MiddleToSuffix(ques,word);//输入中缀表达式转为后缀表达式存入word数组
13 ans[i] &#61; Calculate(word,times);//根据后缀表达式计算结果
14 YueFen(ans[i]);//约分
15 }while((ans[i].deo<&#61;0)||(ans[i].ele<&#61;0)||IsRepeat(ans,i));//若产生负数或分母为0或出现重复则重新生成
16 cout<<question;
17 //DisplayWord(ans[i]);
18 cout<<endl;
19 }

自动生成四则运算

     拓展功能基本完成&#xff0c;但我认为此次在结构上优化还不够好&#xff0c;在生成算式的逻辑上应该还有更为严谨的做法&#xff0c;以后仍需改善。

转:https://www.cnblogs.com/hisbhubhu/p/5246453.html



推荐阅读
  • 题面传送门Solution看到什么最大值最小肯定二分啊。check直接跑一个二分图匹配就好了。orzztl!!!代码实现*mail:mle ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 796.[APIO2012]派遣在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿。在这个帮派里,有一名忍者被称之为Master。 ... [详细]
  • P113:集成日志组件 logback 2彩色日志
    第二步,将控制台的日志改成彩色日志,便于查看修改logback.xml文件。 ... [详细]
  •   并查集是一种群众喜闻乐见的数据结构,其复杂度是数据结构中最奇葩的之一了,Tarjan证明其为阿克曼函数的反函数,在可以想象(不全面的解释啊)的范围内小于等于3。。。我们就把它当做O(1)吧。下面通 ... [详细]
  • 为什么即使Linux服务器的socket关闭,客户端仍能调用一次send函数?
    要弄清这个问题,首先需要知道调用send()发送数据时,发生了什么。当调用send()发送数据时,并不是直接将数据发送到网络中,而是先将待发送的数据放到socket发送缓冲区中,然 ... [详细]
  • C语言函数的定义及其含义
    本文目录一览:1、C语言函数的特点及其定义?2 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 题目描述Takuru是一名情报强者,所以他想利用他强大的情报搜集能力来当中间商赚差价。Takuru的计划是让Hinae帮他去市场上买一个商品,然后再以另一个价格卖掉它。Takur ... [详细]
  • 开发笔记:城市建设
    本文由编程笔记#小编为大家整理,主要介绍了城市建设相关的知识,希望对你有一定的参考价值。本文涉及:cdq分治、MST一道十分精妙的cdq分 ... [详细]
author-avatar
那永A_334
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有