热门标签 | 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



推荐阅读
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • JSOI2010 蔬菜庆典:树结构中的无限大权值问题
    本文探讨了 JSOI2010 的蔬菜庆典问题,主要关注如何处理非根非叶子节点的无限大权值情况。通过分析根节点及其子树的特性,提出了有效的解决方案,并详细解释了算法的实现过程。 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 本文将探讨Java编程语言中对象和类的核心概念,帮助读者更好地理解和应用面向对象编程的思想。通过实际例子和代码演示,我们将揭示如何在Java中定义、创建和使用对象。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • CSS高级技巧:动态高亮当前页面导航
    本文介绍了如何使用CSS实现网站导航栏中当前页面的高亮显示,提升用户体验。通过为每个页面的body元素添加特定ID,并结合导航项的类名,可以轻松实现这一功能。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • 深入解析动态代理模式:23种设计模式之三
    在设计模式中,动态代理模式是应用最为广泛的一种代理模式。它允许我们在运行时动态创建代理对象,并在调用方法时进行增强处理。本文将详细介绍动态代理的实现机制及其应用场景。 ... [详细]
  • 本文介绍了如何使用JavaScript的Fetch API与Express服务器进行交互,涵盖了GET、POST、PUT和DELETE请求的实现,并展示了如何处理JSON响应。 ... [详细]
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社区 版权所有