学习贺利坚老师,计算机混合运算, 做出处理混合运算
用后缀式解决混合运算
v2.0 单片机矩阵按键读取键盘字符, 详细解析博客
更新日志:
v1.0: 实现基本运算功能
v2.0: 在v1.0的基础上,增加stm32单片机, 实现矩阵按键 , 读取用户输入字符, 组合成算式,计算处结果
V1.0
#include <stdio.h>
#include <stdlib.h>
#define MaxOperate 7 //运算符数量
#define MaxSize 100
struct MyStructType
{
char symbol; //运算符
char priority; //优先级
};
//左运算符(进栈运算符)
MyStructType left_symbol[] = {{'=',0},{'(',1},{'+',3},{'-',3},{'*',5},{'/',5},{')',6}};
//右运算符(待栈运算符)
MyStructType right_symbol[] = {{'=',0},{'(',6},{'+',2},{'-',2},{'*',4},{'/',4},{')',1}};
//求左运算符的优先级
int leftsymbol_priority(char seek_symbol)
{
int counter;
int result = 0;
for(counter = 0; counter < MaxOperate; counter++)
{
if(left_symbol[counter].symbol == seek_symbol)
{
result = left_symbol[counter].priority;
}
}
return result;
}
//求右运算符的优先级
int right_symbol_priority(char seek_symbol)
{
int counter;
int result = 0;
for(counter = 0; counter < MaxOperate; counter++)
{
if(right_symbol[counter].symbol == seek_symbol)
{
result = right_symbol[counter].priority;
}
}
return result;
}
bool judging_Type(char judge_char)
{
if( judge_char == '(' ||
judge_char == ')' ||
judge_char == '+' ||
judge_char == '-' ||
judge_char == '*' ||
judge_char == '/' )
{
return true; //是运算符
}
else
{
return false; //不是运算符
}
}
//operation1 和 operation2 运算符优先级的比较结果
int Comparative_priority(char operation1, char operation2)
{
int result;
if(leftsymbol_priority(operation1) == right_symbol_priority(operation2))
{
result = 0;
}
else
if(leftsymbol_priority(operation1) < right_symbol_priority(operation2))
{
result = -1;
}
else
{
result = 1;
}
return result;
}
//将算数表达式 Mixed_operator 转换成后缀表达式 Suffix_expression
void Conversion_expression(char *Mixed_operator,char Suffix_expression[])
{
int counter = 0;
struct
{
char data[MaxSize];//存放运算符
int top; //栈指针
}Operator_stack;
Operator_stack.top = -1;
Operator_stack.top++;
Operator_stack.data[Operator_stack.top] = '=';
//处理混合运算式
while(*Mixed_operator != '\0')
{
//遍历到的字符为数字
if(!judging_Type(*Mixed_operator))
{
while(*Mixed_operator >= '0' && *Mixed_operator <= '9') //把数字加入(从而过滤掉空格)
{
Suffix_expression[counter++] = *Mixed_operator;
Mixed_operator++;
}
Suffix_expression[counter++] = '#'; //数字分隔符
}
else //遍历到的字符为运算符
{
//比较栈顶运算符和此运算符
switch(Comparative_priority(Operator_stack.data[Operator_stack.top],*Mixed_operator))
{
case -1://栈顶运算符优先级低:进栈
Operator_stack.top++;
Operator_stack.data[Operator_stack.top] = *Mixed_operator;
Mixed_operator++;
break;
case 0: //只有括号满足这种情况,退栈,继续扫描
Operator_stack.top--;
Mixed_operator++;
break;
case 1: //栈顶运算符高,则退栈并输出到 Suffix_expression
Suffix_expression[counter++] = Operator_stack.data[Operator_stack.top];
Operator_stack.top--;
break;
}
}
}
//把运算符栈内符号一次性出栈
while(Operator_stack.data[Operator_stack.top] != '=')
{
Suffix_expression[counter] = Operator_stack.data[Operator_stack.top];
counter++;
Operator_stack.top--;
}
Suffix_expression[counter] = '\0';//为后缀式末尾增加结束符号
}
//计算后缀表达式的值
float Calculate_value(char Suffix_expression[])
{
struct
{
float data[MaxSize];
int top;
}data_stack;//存储运算空间的栈
//遍历字符串
int counter = 0;
//遍历字符串
char visit_char = Suffix_expression[counter];
//初始栈顶 -1
data_stack.top = -1;
//数字字符 转 数值中间变量
float numerical_value;
//根据后缀式,进行计算
while(visit_char != '\0')
{
switch(visit_char)
{
case '+':
data_stack.data[data_stack.top - 1] = data_stack.data[data_stack.top - 1] + data_stack.data[data_stack.top];
data_stack.top--;
counter++;
break;
case '-':
data_stack.data[data_stack.top - 1] = data_stack.data[data_stack.top - 1] - data_stack.data[data_stack.top];
data_stack.top--;
counter++;
break;
case '*':
data_stack.data[data_stack.top - 1] = data_stack.data[data_stack.top - 1] * data_stack.data[data_stack.top];
data_stack.top--;
counter++;
break;
case '/':
if(data_stack.data[data_stack.top] != 0)
{
data_stack.data[data_stack.top - 1] = data_stack.data[data_stack.top - 1] / data_stack.data[data_stack.top];
data_stack.top--;
counter++;
}
else //除零错误
{
printf("\n\t除零错误!\n");
exit(0); //异常退出
}
break;
default:
numerical_value = 0;//将数字字符转换成数值存放在 numerical_value 中
while(visit_char >= '0' && visit_char <= '9')
{
numerical_value = 10 * numerical_value + visit_char - '0';
counter++;
visit_char = Suffix_expression[counter];
}
//处理数字入数据处理栈
data_stack.top++;
data_stack.data[data_stack.top] = numerical_value;
counter++;//跳过后缀式数字后的'#'
break;
}
//选中要处理的字符
visit_char = Suffix_expression[counter];
}
//返回计算结果
return data_stack.data[data_stack.top];
}
int main()
{
//混合运算式
char Mixed_operator[] = "(56-20)/(4+2)-33+9*32";//改为单片机输入
//后缀表达式
char Suffix_expression[MaxSize];
//转换表达式(混合运算式 ==> 后缀表达式)
Conversion_expression(Mixed_operator,Suffix_expression);
printf("\n中缀表达式:%s\n",Mixed_operator);
printf("\n后缀表达式:%s\n",Suffix_expression);
printf("\n表达式的值:%g\n",Calculate_value(Suffix_expression));
return 0;
}