*********************************************************************************************************
本文作者科大MF22某班Noah懒羊羊同学,为大家提供一个作业思路,请勿直接copy!!!一起进步学习~
**********************************************************************************************************
目录
Noah_Cal_Expression_With_Stack.h
1. 波兰式计算
+ 2 * 3 - 5 1= 2 + 3 * (5 - 1)=14(11分)
+ + 2 * 3 - 7 4 / 8 4=2+3*(7-4)+8/4=13(12分)
2. 逆波兰式计算
2 3 5 1 - * += 2 + 3 * (5 - 1)=14(11分)
9 3 1 – 3* + 10 2 / +=9+(3-1)*3+10/2=20(12分)
3. 中缀式计算
(1)4 + 2 * 3 – 10 / 5 计算结果,应输出8(12分);
(2)(4+2)*3 – 10 / 5 计算结果,应输出16(12分);
例如:
输入表达式有非法字符,(2分)
如:+ 2 A 、 2 3 A - 、 4 + a
如:+ 2 2 2 、 2 2 2 + 、 2 + 2 2 、+ + 2 2 、2 2 + +、 2 + + 2
如( 4 + 2 * 3、4 + 2)* 3。
程序中应用到的主要数据结构是顺序栈。


主要变量说明:
| 变量 | 类型 | 说明 |
| sq_stack | 结构体 | 栈的结构体 |
| *base | 栈的底部元素指针 | 用于访问栈的底部元素,控制栈的存储,计算站的元素个数等 |
| *top | 栈的顶部元素指针 | 用于访问栈的顶部元素,控制栈的存储,计算站的元素个数等 |
| stack_size | int | 顺序栈的内存空间大小(可存储的元素个数) |
| expression | string | 需要计算表达式 |
| STACK_INIT_SIZE | 宏定义 | 初始化存储空间大小 |
| STACK_INCREMENT_SIZE | 宏定义 | 存储空间分配增量大小 |
| STK_Elemtype | 宏定义 | 栈中元素的数据类型 |
程序主要包含Noah_stack.h、Noah_expression_normaltoRPN.h、Noah_Cal_Expression_With_Stack.h头文件和main.cpp主文件,其中Noah_stack.h是栈数据结构的实现代码头文件,Noah_expression_normaltoRPN.h是将中缀表达式转为后缀表达式(逆波兰式)的代码集合头文件、Noah_Cal_Expression_With_Stack.h是调用栈数据结构和表达式转换代码实现的计算不同表达式的功能的代码集合头文件,main.cpp中主要实现菜单和功能界面的交互以及头文件中函数的调用。其具体结构如下图所示。

调试功能一:Polish expression calculator
计算波兰式表达式

测试数据选择:
问题及解决方法:
调试功能二:Inverse Polish expression calculator
计算逆波兰式表达式

测试数据选择:
问题及解决方法:
调试功能三:Infix expression calculator
计算中缀表达式

测试数据选择:
问题及解决方法:
无
调试功能四:稳健性测试

测试数据选择:
问题及解决方法:
无
(1)STK_Elemtype Polish_type_calculate(string expression)
时间复杂度:O(n)
空间复杂度:O(n)
(2)STK_Elemtype Inverse_Polish_type_calculate(string expression)
时间复杂度:O(n)
空间复杂度:O(n)
(3)STK_Elemtype Normal_type_calculate(string expression)
时间复杂度:O(n)
空间复杂度:O(n)
测试功能一:Polish expression calculator
| 测试用例 | 结果 | 分析 |
| + 2 * 3 - 5 1 |
| √,波兰式计算正确 |
| + + 2 * 3 - 7 4 / 8 4 |
| √ |
调试功能二:Inverse Polish expression calculator
| 测试用例 | 结果 | 分析 |
| 2 3 5 1 - * + |
| √,逆波兰式计算正确 |
| 9 3 1 – 3 * + 10 2 / + |
| √ |
测试功能三:Infix expression calculator
| 测试用例 | 结果 | 分析 |
| 4 + 2 * 3 – 10 / 5 |
| √,中缀表达式计算正确 |
| ( 4 + 2) * 3 – 10 / 5 |
| √ |
调试功能四:健壮性测试
| 测试用例 | 结果 | 分析 |
| 1 + ( 5 * 6 – 10 |
| √ |
| a , a + 5 |
| √ |
| 2 3 A – |
| √ |
| 4 + 2) * 3 |
| √ |
| + + 2 2 |
| √ |
- #ifndef NOAH_STACK_H_INCLUDED
- #define NOAH_STACK_H_INCLUDED
- #include
- #define STACK_INIT_SIZE 100//初始化存储空间大小
- #define STACK_INCREMENT_SIZE 10//存储空间分配增量大小
- #define STK_Elemtype float
- typedef struct{
- STK_Elemtype *base;
- STK_Elemtype *top;
- int stack_size;
- }sq_stack;
-
- //初始化栈(顺序栈)
- void initStack(sq_stack &s){
- s.base = (STK_Elemtype *)malloc(STACK_INIT_SIZE * sizeof(STK_Elemtype));
- /*
- if(!s.base)
- exit(overflow_error);//内存空间不足初始化失败,程序退出
- */
- s.top = s.base;
- s.stack_size = STACK_INIT_SIZE;
- }
- //为顺序栈重新分配空间并将空间扩大incrementsize*sizeof(element)
- void incrementStack(sq_stack &s,int incrementsize){
- s.base =(STK_Elemtype *)realloc(s.base,(s.stack_size + incrementsize)*sizeof(STK_Elemtype));
- /*
- if(!s.base)
- exit(overflow_error);//内存空间不足,增加size失败,程序退出
- */
- s.top = s.base + s.stack_size;
- s.stack_size += incrementsize;
- }
- //判断链表是否为空
- int isStackempty(sq_stack s){
- if(s.base==s.top)
- return 1;//空
- else
- return 0;//非空
- }
- //判断链表是否存满
- int isStackfull(sq_stack s){
- if(s.top - s.base >=s.stack_size)
- return 1;//存满
- else
- return 0;//没有存满
- }
- //取栈顶元素
- STK_Elemtype GetTop(sq_stack s){
- //首先判断元素是否为空
- if(isStackempty(s)){
- cout << "The stack is Empty, return -1." << endl;
- return STK_Elemtype(-1);
- }
- else
- return *(s.top - 1);
- }
-
- //入栈
- void push(sq_stack &s,STK_Elemtype e){
- if(isStackfull(s))
- incrementStack(s,STACK_INCREMENT_SIZE);
- *s.top++ = e;
- }
-
- //出栈
- STK_Elemtype pop(sq_stack &s){
- if(isStackempty(s)){
- cout << "The stack is Empty, return -1." << endl;
- return STK_Elemtype(-1);
- }
- else
- //cout<<"pop:"<<*(s.top-1);
- return *--s.top;
-
- }
- //返回链表中的元素个数
- int len_Stack(sq_stack s){
- return s.top-s.base;
- }
-
- //打印链表中所有元素
- void Display_Stack(sq_stack s){
- if(isStackempty(s)){
- printf("The stack is Empty.");
- return ;
- }
- for(int i = 0 ; i<len_Stack(s);i++)
- printf("%.2f ",*(s.base+i));
- }
- #endif // NOAH_STACK_H_INCLUDED
- #ifndef NOAH_CAL_EXPRESSION_WITH_STACK_H_INCLUDED
- #define NOAH_CAL_EXPRESSION_WITH_STACK_H_INCLUDED
- #include "Noah_stack.h"
- #include "Noah_expression_normaltoRPN.h"
- #include
- #include
- #include
- #include
- using namespace std;
-
- string input_expression();
- int check_expression(string expression);
- STK_Elemtype Polish_type_calculate(string expression);
- STK_Elemtype Inverse_Polish_type_calculate(string expression);
- STK_Elemtype Normal_type_calculate(string expression);
-
-
-
- //输入一个表达式
- string input_expression(){
- int legal = 0;
- char expression_chars[256];
- string expression;
- while(!legal){
- cout <<"Please input the expression:"<
- cin.ignore();
- cin.getline(expression_chars,256);
- expression = expression_chars;
- legal = check_expression(expression);
- if(!legal){
- cout<<"Expression illegal, please input again."<
- //char expression_chars[256] = "";
- }
- }
- return expression;
- }
- //判断表达式是否合法,合法返回1,不合法返回0
- int check_expression(string expression){
- //三种不合法的方式
- int expression_error_illegal_char = 0;
- int expression_error_unaligment_numberandoperation = 0;
- int expression_error_unaligment_bracket = 0;
- //中间控制变量
- int operands_num = 0;
- int operation_num = 0;
- int bracket_left = 0;
- int bracket_right = 0;
- string temp = "";
- //按字符判断,循环
- for (decltype(expression.size()) index = 0; index != expression.size(); index++){
- char x = expression[index];
- //cout<
- if(temp.size()>0 && x==' '){
- temp = "";
- operands_num++;
- }
- if(x=='('||x==')'||x==' '){
- if(x=='(')
- bracket_left++;
- else if(x == ')')
- bracket_right++;
- continue;
- }
- if(x=='+'||x=='-'||x=='*'||x=='/'||x=='%'||x=='^')
- operation_num++;
- else if(x>='0'&&x<='9'){
- temp +=x;
- if(index == expression.size()-1)
- operands_num++;
- }
- else
- expression_error_illegal_char = 1;//有非法字符
- //cout<
- }
- if(operands_num!=(operation_num+1))
- expression_error_unaligment_numberandoperation = 1;
- if(bracket_left!=bracket_right)
- expression_error_unaligment_bracket = 1;
-
- //检查结果输出
- if(expression_error_illegal_char||expression_error_unaligment_bracket||expression_error_unaligment_numberandoperation){
- cout<
" "<<"is illegal!"< - if(expression_error_illegal_char)
- cout<<"The input expression has an invalid character."<
- if(expression_error_unaligment_numberandoperation)
- cout<<"The input expression operands do not match the number of operators."<
- if(expression_error_unaligment_bracket)
- cout<<"The expression brackets are not as paired."<
- return 0;//expression非法
- }
- return 1;//expression合法
- }
- //计算波兰式
- STK_Elemtype Polish_type_calculate(string expression){
- sq_stack s;
- initStack(s);
- //逆序遍历表达式字符串
- string temp = "";
- for (decltype(expression.size()) index = expression.size()-1; index != -1; index--){
- char x = expression[index];
- if(temp.size()>0 && x==' '){
- push(s,stof(temp));
- temp = "";
- }
- /*
- cout<
- Display_Stack(s);
- cout<
- */
- if(x=='+'||x=='-'||x=='*'||x=='/'||x=='%'||x=='^'){
- switch(x){
- case('+'):
- push(s,pop(s)+pop(s));break;
- case('-'):
- push(s,(-pop(s)+pop(s)));break;
- case('*'):
- push(s,pop(s)*pop(s));break;
- case('/'):
- push(s,pop(s)/pop(s));break;
- case('%'):
- {
- int temp1 = int(pop(s));
- int temp2 = int(pop(s));
- push(s,temp1%temp2);break;
- }
- case('^'):
- {
- float temp1 = pop(s);
- float temp2 = pop(s);
- push(s,pow(temp1,temp2));break;
- }
- }
- }
- else if(x>='0'&&x<='9'){
- temp = x + temp;
- if(index==0)
- push(s,stof(temp));
- }
- }
- return pop(s);
- }
-
- //计算逆波兰式
- STK_Elemtype Inverse_Polish_type_calculate(string expression){
- sq_stack s;
- initStack(s);
- //正序遍历表达式字符串
- string temp = "";
- for (decltype(expression.size()) index = 0; index != expression.size(); index++){
- char x = expression[index];
- if(temp.size()>0 && x==' '){
- push(s,stof(temp));
- temp = "";
- }
- /*
- cout<
- Display_Stack(s);
- cout<
- */
- if(x=='+'||x=='-'||x=='*'||x=='/'||x=='%'||x=='^'){
- switch(x){
- case('+'):
- push(s,pop(s)+pop(s));break;
- case('-'):
- push(s,(0-pop(s)+pop(s)));break;
- case('*'):
- push(s,pop(s)*pop(s));break;
- case('/'):
- push(s,1/pop(s)*pop(s));break;
- case('%'):
- {
- int temp1 = int(pop(s));
- int temp2 = int(pop(s));
- push(s,temp2%temp1);break;
- }
- case('^'):
- {
- float temp1 = pop(s);
- float temp2 = pop(s);
- push(s,pow(temp2,temp1));break;
- }
- }
- }
- else if(x>='0'&&x<='9'){
- temp = temp + x;
- if(index==expression.size()-1)
- push(s,stof(temp));
- }
- }
- return pop(s);
- }
-
- //计算中缀表达式,先转为逆波兰式再计算逆波兰式
- STK_Elemtype Normal_type_calculate(string expression){
- return Inverse_Polish_type_calculate(RPN(expression));
- }
-
- #endif // NOAH_CAL_EXPRESSION_WITH_STACK_H_INCLUDED
Noah_expression_noemaltoRPN.h
- #ifndef NOAH_EXPRESSION_NORMALTORPN_H_INCLUDED
- #define NOAH_EXPRESSION_NORMALTORPN_H_INCLUDED
- #include
- #include
- #include
- #include "Noah_stack.h"
-
- using namespace std;
- int priority_func(char op);
-
- //判断运算符的优先级
- int priority_func(char op)
- {
- int priority;
- if(op == '*' || op == '/') priority = 2;
- if(op == '+' || op == '-') priority = 1;
- if(op == '(') priority = 0;
- return priority;
- }
-
- //将中缀表达式转为逆波兰式
- string RPN(string str)
- {
- string str1="";
- stack<char> s;
- int i;
- string temp = "";
- for(i = 0; i < str.size(); i ++ )
- {
- //cout<
- if(str[i]==' '){
- //cout<
- if(temp.size()>0){
- str1 = str1+ " " + temp;
- temp = "";
- }
- continue;
- }
- //是数字的情况下直接输出
- if(str[i] >= '0' && str[i] <= '9' )
- {
- temp = temp+string(1,str[i]);
- if(i==str.size()-1)
- str1 = str1+ " " + temp;
- }
- else //不是数字的情况分类讨论进行判断
- {
- //栈为空时直接入栈
- if(s.empty()) s.push(str[i]);
- //左括号入栈
- else if(str[i] == '(') s.push(str[i]);
- //如果是右括号,只要栈顶不是左括号,就弹出并输出
- else if(str[i] == ')')
- {
- while(s.top() != '(')
- {
- str1 = str1+ " " + s.top();
- s.pop();
- }
- //弹出左括号,但不输出
- s.pop();
- }
- else
- {
- //栈顶元素的优先级大于等于当前的运算符,就将其输出
- while(priority_func(str[i]) <= priority_func(s.top()))
- {
- str1 = str1+ " " + s.top();
- s.pop();
- //栈为空,停止
- if(s.empty()) break;
- }
- s.push(str[i]);
- }
- }
- }
- //最后,如果不为空,就把所以的元素全部弹出
- while(!s.empty())
- {
- str1 = str1+ " " + s.top();
- s.pop();
- }
- string str2 = str1.substr(1,str1.size());
- str1 = str2;
- return str1;
- }
-
- #endif // NOAH_EXPRESSION_NORMALTORPN_H_INCLUDED
Main.cpp
- #include
- using namespace std;
- #include
- #include
- #include
- #include "Noah_Cal_Expression_With_Stack.h"
- void Menue_gui();
- void func1();
- void func2();
- void func3();
-
- int main()
- {
- while(1){
- Menue_gui();
- int func;
- scanf("%d",&func);
- switch(func){
- case 0:
- exit(0);
- case 1:
- func1();break;
- case 2:
- func2();break;
- case 3:
- func3();break;
- default:
- printf("Input error! Please try again!");
- }
- printf("\n");
- system("pause");
- }
- return 0;
- }
-
- //菜单界面
- void Menue_gui(){
- system("cls");//清屏
- printf("****************Polish, inverse Polish, and infix expression calculators*********************\n");
- printf("*********************************************************************************************\n");
- printf("Menue:\n");
- printf("\nExit this program------------------------------------------------------0.\n");
- printf("\nPolish expression calculator-------------------------------------------1.\n");
- printf("\nReverse Polish expression calculator-----------------------------------2.\n");
- printf("\nInfix expression calculator--------------------------------------------3.\n");
- printf("\n**********************************************************************************************\n");
- printf("Choose the function you want to use(input number):\n");
- }
-
- //功能1界面
- void func1(){
- system("cls");//清屏
- printf("-----ENTER FUNCTION : Polish expression calculator--1.-----\n");
- printf("Input Polish expression(example:+ 2 * 3 - 5 1)\n");
- string polish_expression;
- polish_expression = input_expression();
- float reslut = float(Polish_type_calculate(polish_expression));
- printf("Result:%.2f",reslut);
- }
-
- //功能2界面
- void func2(){
- system("cls");//清屏
- printf("-----ENTER FUNCTION : Inverse Polish expression calculator--2-----.\n");
- printf("Input Inverse Polish expression(example:2 3 5 1 - * +)\n");
- string Inverse_polish_expression;
- Inverse_polish_expression = input_expression();
- float reslut = float(Inverse_Polish_type_calculate(Inverse_polish_expression));
- printf("Result:%.2f",reslut);
- }
-
- //功能3界面
- void func3(){
- system("cls");//清屏
- printf("-----ENTER FUNCTION : Infix expression calculator--3.-----\n");
- printf("Input Infix expression(example:4 + 2 * 3 – 10 / 5)\n");
- string Infix_expression;
- Infix_expression = input_expression();
- float reslut = float(Normal_type_calculate(Infix_expression));
- printf("Result:%.2f",reslut);
- }
-
相关阅读:
threejs官方demo学习(1):animation
springcloud新闻发布系统源码
VulnHub Tre
使用vite 搭建vue 3的项目
【HUST】网安纳米|2023年研究生纳米技术考试参考
常用电子元器件基础知识
爆赞!GitHub首本前端开发实战Vue.js3,标星果然百万名不虚传
DJYOS物联屏:工业HMI里的显控异构计算的超稳定解决方案
【python】bin/dec/hex/bnr进制转换函数及fp32转十六进制
如何在 Vim 中剪切、复制和粘贴
-
原文地址:https://blog.csdn.net/standingflower/article/details/127923498