Github链接

表达式用栈的实现

表达式的生成过程用流程图来展示

我们通过生成一个个a+b型的小表达式,来获得最终符合用户要求的表达式。

首先由用户决定(输入y/n):

  • 表达式中出现数字的绝对值范围
  • 表达式中出现数字的个数
  • 是否允许乘除
  • 是否允许分数
  • 是否允许括号

程序根据用户的输入来生成表达式,可以让用户对题目进行“私人订制”,生成多种多样的表达式。

然后通过对表达式的唯一性和是否除零的检验,如果通过就放入集合中,否则就重新生成。

至于合法性的检验,只要确保每一个a+b型的小表达式合法,则最终的表达式就合法。

代码

/*************************************************************
文件名:Expression.cpp
作者:盖嘉轩 日期:2017/05/09
描述: 定义——类:Expression
主要功能:表达式的生成、计算
作者:盖嘉轩 日期:2017/05/10
*************************************************************/
#include"expression.h"
#include<iostream>
#include<sstream>
#include<vector>
#include<stack>
using namespace std;Expression::Expression() { }
/*随机生成一个运算符*/
char Expression::RandomOperation(char ifMultiplyDivide)
{int tmp;if (ifMultiplyDivide == 'y') //允许乘除{tmp = RandomNumber(1, 4);switch (tmp)//随机生成运算符{case 1:{return '+';break;}case 2:{return '-';break;}case 3:{return '*';break;}case 4:{return '/';break;}}}else //不允许乘除{tmp = RandomNumber(1, 2);switch (tmp){case 1:{return '+';break;}case 2:{return '-';break;}}}
}/*判断表达式是否唯一,重复为false,唯一为true */
bool Expression::IsOnly(string expression)
{int count = 0;for (unsigned i = 0; i < m_expressionUint.size(); i++){if (expression != m_expressionUint[i]){count++;}else{break;}}if (count == m_expressionUint.size()) //如果为唯一{return true;}else// 如果重复{return false;}
}/*生成一个中缀表达式*/
string Expression::GenerateInfixExpression(int low, int high, int parameterNumber, char ifMultiplyDivide, char ifFraction, char ifBracket)
{string expression; for (; ;){string parameter1, parameter2; bool ifFirst = true; //是否已生成第一个小表达式,是为true,否为falsefor (int j = 0; j < parameterNumber - 1; j++){int ntmp;char sign = RandomOperation(ifMultiplyDivide); //运算符if (ifFraction == 'y') //允许分数{ntmp = RandomNumber(1, 3);switch (ntmp){case 1: //整数和整数{stringstream sstmp1, sstmp2;sstmp1 << RandomNumber(low, high);sstmp1 >> parameter1;sstmp2 << RandomNumber(low, high);sstmp2 >> parameter2;sstmp1.clear();sstmp2.clear();break;}case 2:  //整数和真分数{stringstream sstmp;sstmp << RandomNumber(low, high);sstmp >> parameter1;sstmp.clear();Fraction fraction2;fraction2.GetFraction(low, high);fraction2.Simplify();parameter2 = fraction2.TransferIntoStringNoInt();break;}case 3: //分数和分数 {Fraction fraction1, fraction2;fraction1.GetFraction(low, high);fraction1.Simplify();fraction2.GetFraction(low, high);fraction2.Simplify();parameter1 = fraction1.TransferIntoStringNoInt();parameter2 = fraction2.TransferIntoStringNoInt();break;}}}else //不允许分数{stringstream sstmp1, sstmp2;sstmp1 << RandomNumber(low, high);sstmp1 >> parameter1;sstmp2 << RandomNumber(low, high);sstmp2 >> parameter2;sstmp1.clear();sstmp2.clear();}if (ifBracket == 'y') //允许括号{ntmp = RandomNumber(1, 4);switch (ntmp){case 1: //无括号{if (ifFirst){expression = parameter1 + sign + parameter2;ifFirst = false;}else{expression = expression + sign + parameter1;}break;}case 2: //无括号{if (ifFirst){expression = parameter2 + sign + parameter1;ifFirst = false;}else{expression = parameter1 + sign + expression;}break;}case 3: //有括号{if (ifFirst){expression = "[" + parameter1 + sign + parameter2 + "]";ifFirst = false;}else{expression = "[" + expression + sign + parameter1 + "]";}break;}case 4: //有括号{if (ifFirst){expression = "[" + parameter2 + sign + parameter1 + "]";ifFirst = false;}else{expression = "[" + expression + sign + parameter1 + "]";}break;}}}else //不允许括号{ntmp = RandomNumber(1, 2);switch (ntmp){case 1:{if (ifFirst){expression = parameter1 + sign + parameter2;ifFirst = false;}else{expression = expression + sign + parameter1;}break;}case 2:{if (ifFirst){expression = parameter2 + sign + parameter1;ifFirst = false;}else{expression = parameter1 + sign + expression;}}}}}m_infix = expression;if ((IsOnly(expression)) && (CalculateResult() != "non_comformance")) //判断新生成的表达式是否重复以及是否出现除0的情况{m_expressionUint.push_back(expression);break;}}return expression;
}/*将中缀表达式转化为后缀表达式 */
void Expression::TransferInfixIntoPostfix()
{unsigned i = 0;int j = 0;stack<char> signStack;//符号栈 while (i < m_infix.size()){if ((m_infix[i] >= '0') && (m_infix[i] <= '9'))//判断数字 {while ((m_infix[i] >= '0') && (m_infix[i] <= '9')){m_postfix[j] = m_infix[i];i++;j++;}m_postfix[j] = '!'; //标识单个整数j++;}if (m_infix[i] == '(') //判断分数 {while (m_infix[i] != ')') //将分数作为整体 {m_postfix[j] = m_infix[i];i++;j++;}m_postfix[j] = m_infix[i];i++;j++;}if ((m_infix[i] == '+') || (m_infix[i] == '-')) //判断加减{while ((!signStack.empty()) && (signStack.top() != '[')){m_postfix[j] = signStack.top();j++;signStack.pop();}signStack.push(m_infix[i]);}if ((m_infix[i] == '*') || (m_infix[i] == '/'))//判断乘除  {while ((!signStack.empty()) && (signStack.top() != '[') && ((signStack.top() == '*') || (signStack.top() == '/'))){m_postfix[j] = signStack.top();j++;signStack.pop();}signStack.push(m_infix[i]);}if (m_infix[i] == '[') //判断'['{signStack.push(m_infix[i]);}if (m_infix[i] == ']')  //判断']' {while (signStack.top() != '['){m_postfix[j] = signStack.top();j++;signStack.pop();}signStack.pop();}i++;}while (!signStack.empty())//当有残余运算符时 {m_postfix[j] = signStack.top();j++;signStack.pop();}m_postfix[j] = '\0';  //设置终止符
}/*计算后缀表达式的值*/
string Expression::CalculateResult()
{int i = 0;int point = -1; bool ifDivideZero = false; //是否除零,是为true,否为falseFraction numberStack[kMax]; //数栈TransferInfixIntoPostfix();while ((m_postfix[i] != '\0') && (i<1000)){if ((m_postfix[i] >= '0') && (m_postfix[i] <= '9'))//整数入栈  {double k = 0; //int会计算出错while ((m_postfix[i] >= '0') && (m_postfix[i] <= '9')){k = 10 * k + m_postfix[i] - '0';i++;}point++;numberStack[point].TransferIntIntoFraction(k, 1);}elseif (m_postfix[i] == '(') //分数入栈{double up = 0, down = 0;//int会计算出错  i++;while (m_postfix[i] != '\\'){up = 10 * up + m_postfix[i] - '0';i++;}i++;while (m_postfix[i] != ')'){down = 10 * down + m_postfix[i] - '0';i++;}point++;numberStack[point].TransferIntIntoFraction(up, down);}else //进行计算{point--;switch (m_postfix[i]){case '+':{numberStack[point] = numberStack[point] + numberStack[point + 1];break;}case '-':{numberStack[point] = numberStack[point] - numberStack[point + 1];break;}case '*':{numberStack[point] = numberStack[point] * numberStack[point + 1];break;}case '/':{if (numberStack[point + 1].isDivisorZero()) //如果除数为零{ifDivideZero = true;}numberStack[point] = numberStack[point] / numberStack[point + 1];}}}i++;}if ((!ifDivideZero) && (numberStack[point].IsInt())) //如果没有除零以及得数为整数{return numberStack[point].TransferIntoString();}else{return "non_comformance";}
}

学习MFC

MFC(Microsoft Foundation
Classes),全称微软基础类库,是一个微软公司提供的类库(class libraries),MFC以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。可以用于C++界面编程

优点:

MFC的主要优点是可以用面向对象的方法来调用Windows API,以及应用程序开发的便捷。MFC将很多应用程序开发中常用的功能自动化,并且提供了文档框架视图结构和活动文档这样的便于自定义的应用程序框架。同时,在Visual C++内部也内建了很多对MFC的例如类向导这样的支持以减少软件开发的时间,使用类向导可以生成从hello world这样的简单程序到活动文档服务器这样的复杂程序。MFC的消息映射机制也避免了使用性能较低的庞大虚函数表。

缺点:

虽然MFC的源代码对用户是完全开放的,但是MFC的一些封装过程过于复杂,以致于新用户很难迅速掌握MFC的应用程序框架,以及在调试中定位问题的位置。同时,很多MFC对象不是线程安全的,致使在跨线程访问MFC对象时需要编写额外的代码。另外,MFC的很多类依赖于应用程序向导生成的代码,使得在使用Visual C++中其他类型的应用程序向导生成的工程中添加MFC支持的难度大大增加。

心得

虽然已经做了那么多次的作业了,但是每一次自学新知识还是有一些“混乱”!在网上找一篇合适的博客都要找好久,一旦遇到问题就急得不行,可能我还是需要在历练一下。

转载于:https://www.cnblogs.com/gjx031602211/p/6925988.html

2017《面向对象程序设计》课程作业六相关推荐

  1. 2017福州大学面向对象程序设计课程作业六

    作业链接 课程第六次作业统计完成,本次作业满分100分,统计结果如下: 学号 姓名 作业地址 分数 111500206 赵畅 http://www.cnblogs.com/ZCplayground/p ...

  2. 2017福州大学面向对象程序设计课程作业八

    作业链接 课程第七次作业统计完成,本次作业满分100分,统计结果如下: 学号 姓名 作业地址 分数 111500206 赵畅 http://www.cnblogs.com/ZCplayground/p ...

  3. 2017福州大学面向对象程序设计课程作业七

    作业链接 课程第七次作业统计完成,本次作业满分100分,统计结果如下: 学号 姓名 作业地址 分数 111500206 赵畅 http://www.cnblogs.com/ZCplayground/p ...

  4. 2017福州大学面向对象程序设计课程作业五

    作业链接 课程第五次作业统计完成,本次作业满分100分,统计结果如下: 学号 姓名 作业地址 分数 111500206 赵畅 http://www.cnblogs.com/ZCplayground/p ...

  5. 2017福州大学面向对象程序设计课程作业四

    作业链接 课程第四次作业统计完成,本次作业满分100分,统计结果如下: 学号 姓名 作业地址 分数 111500206 赵畅 http://www.cnblogs.com/ZCplayground/p ...

  6. 2017《面向对象程序设计》作业四

    2017<面向对象程序设计>作业四 林燊 031602325 https://www.cnblogs.com/linshen/ github链接:https://github.com/Tr ...

  7. C++面向对象程序设计大作业:魔兽世界(三):开战

    C++面向对象程序设计大作业:魔兽世界(三):开战 问题描述 问题分析 代码 问题描述 问题来自于北京大学郭炜老师的C++慕课的大作业 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部.两个司令部 ...

  8. C++《面向对象程序设计课程设计》

    C++<面向对象程序设计课程设计> <面向对象程序设计课程设计>课程说明 适用专业:计算机科学与技术 课程周数:5周 一.根据计算机科学与技术专业人才培养方案制订. (一)课程 ...

  9. 面向对象程序设计课程进度条

    面向对象程序设计课程进度条 周次 (阅读/编写)代码行数 发布微博量/博客评论数量 课堂/课余学习时间(小时) 最满意的编程任务 第一周 42/25 1/0 4/3 乘法表实验 第二周 150/100 ...

  10. “2017面向对象程序设计(Java)第十一周学习总结”存在问题的反馈及教学安排...

    "2017面向对象程序设计(Java)第十一周学习总结"存在问题的反馈及教学安排 1."提出表扬的同学:姜依萍,王雪玲,徐楠,相文君,赵晓 未提交作业的同学:任红强,王瑞 ...

最新文章

  1. 关于Kanas.Net框架的一些背景
  2. 再次学习javascript中的參数传递
  3. codeforce 606A - Magic Spheres
  4. sqlmap使用_sqlmap于sql labs下使用
  5. 《Spring源码深度解析》 PDF
  6. LeetCode 剑指Offer 64.求1,2到n的和, 不使用循环/判断及乘除
  7. java最常见的runtime_Java常见runtime exception
  8. 蚂蚁金服一面二面试题及答案,职位Java高级工程师
  9. 安装rpm包完成却报错(桌面软件类安装包),可以在usr/share/applications目录下找到图标打开
  10. OC高效率52之提供“全能初始化”方法
  11. 指针数组vs数组指针 指针函数vs函数指针
  12. cocos2d-x 3.1.1 学习笔记[21]cocos2d-x 创建过程
  13. php匹配车牌号,分享一个非常全的php正则验证车牌格式的函数
  14. 协程学习一:nty协程的设计原理及效率分析
  15. python设置excel边框_用Python操作Excel电子表格?单元格边框如何设置?样式有哪些?...
  16. matlab的textscan与textread区别(转)
  17. 2021全国特种设备-G3锅炉水处理模拟考试题库一[安考星]
  18. 563. 二叉树的坡度【我亦无他唯手熟尔】
  19. 深蓝学院-视觉SLAM理论与实践-第十二期-第3章作业
  20. 一文彻底读懂三极管的工作原理,最通俗的解释,看完就明白了!

热门文章

  1. 【Leetcode】Palindrome Number
  2. [转]消息队列软件大比拼
  3. 订体育馆订健身房的方法
  4. 小创业项目组的管理和实践:快速迭代的思考
  5. macOS的关于屏幕录制的快捷键和操作
  6. C++返回栈上的数组(局部变量)问题探索
  7. C++用参数返回结果与用返回值返回结果的思考
  8. 关于IOCP完成端口的文章
  9. KMP算法~看的清楚~
  10. python基础:并行遍历ZIP()函数介绍