问题:用户输入一个包含“+”、“-”、“*”、“/”、正整数和圆括号的合法数学表达式,计算该表达式的运算结果
C语言
我这里是使用两个栈实现的,直接对中缀表达式进行运算的
输入的算式以#结尾
除此之外该问题还可以使用一个栈,如:先转化成后缀表达式;或者使用char型共享栈,操作数进出栈时进行类型转换即可。
Evaluation.h
#ifndef EVALUATION_H_INCLUDED
#define EVALUATION_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
//操作数
typedef struct Operand
{
int Data[MAXSIZE];
int top;
}Rand;
//运算符
typedef struct Operator
{
char Data[MAXSIZE];
int top;
}Rator;
//定义栈存放操作数和运算符
Rand operands;
Rator operators;
//初始化栈
void InitOperand(Rand *ra);
void InitOperator(Rator *op);
//判栈空
int EmptyRand(Rand *ra);
int EmptyRator(Rator *op);
//进栈
int PushRand(Rand *ra,int e);
int PushRator(Rator *op,char e);
//出栈
int PopRand(Rand *ra,int *e);
int PopRator(Rator *op,char *e);
//取栈顶元素
int GetTopRand(Rand *ra);
char GetTopRator(Rator *op);
//判断字符是否为运算符
int InOp(char ch);
//判断运算符优先级
int Priority(char s);
//比较运算符优先级
int Precede(char op1,char op2);
//判断符号并运算
int Calculation(int a,int b,char c);
//计算表达式
int ExpCalculation(Rand *ra,Rator *op);
#endif // EVALUATION_H_INCLUDED
Evaluation.c
#include "Evaluation.h"
//初始化栈
void InitOperand(Rand *ra)
{
ra->top = -1;
}
void InitOperator(Rator *op)
{
op->top = -1;
}
//栈栈空
int EmptyRand(Rand *ra)
{
ra->top = -1;
return 0;
}
int EmptyRator(Rator *op)
{
op->top = -1;
return 0;
}
//进栈
int PushRand(Rand *ra,int e)
{
if(ra->top == MAXSIZE-1)
return 0;
ra->top++;
ra->Data[ra->top] = e;
return 1;
}
int PushRator(Rator *op,char e)
{
if(op->top == MAXSIZE-1)
return 0;
op->top++;
op->Data[op->top] = e;
return 1;
}
//出栈
int PopRand(Rand *ra,int *e)
{
if(ra->top == -1)
return 0;
*e = ra->Data[ra->top];
ra->top--;
return 1;
}
int PopRator(Rator *op,char *e)
{
if(op->top == -1)
return 0;
*e = op->Data[op->top];
op->top--;
return 1;
}
//取栈顶元素
int GetTopRand(Rand *ra)
{
if(ra->top == -1)
return 0;
return ra->Data[ra->top];
}
char GetTopRator(Rator *op)
{
if(op->top == -1)
return 'N';
return op->Data[op->top];//
}
//判断字符是否为运算符
int InOp(char ch)
{
if(ch == '(' || ch == ')' || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '#')
return 1;
return 0;
}
//判断运算符优先级
int Priority(char s)
{
switch(s)
{
case '(':
return 4;
case '*':
case '/':
return 3;
case '+':
case '-':
return 2;
case ')':
return 1;
default:
return 0;
}
}
//比较运算符优先级
int Precede(char op1,char op2)
{
if(Priority(op1) < Priority(op2))
return 0;
return 1;
}
//判断符号并运算
int Calculation(int a,int b,char c)
{
switch(c)
{
case '+':
return a+b;
case '-':
return a-b;
case '*':
return a*b;
case '/':
if(b == 0)
exit(1);
return a/b;
}
}
//计算表达式
int ExpCalculation(Rand *ra,Rator *op)
{
int a,b;
char ch,s;
PushRator(op,'#');
printf("请输入要计算的算式(以#结尾):");
ch = getchar();
while(ch != '#' || GetTopRator(op) != '#')
{
if(!InOp(ch))
{
int temp;
temp = ch - '0';
ch = getchar();
while(!InOp(ch))
{
temp = temp * 10 + ch - '0';
ch = getchar();
}
PushRand(ra,temp);
}
else
{
if(GetTopRator(op) == '(')
{
if(ch == ')')
PopRator(op,&s);
else
PushRator(op,ch);
ch = getchar();
}
else
{
if(!Precede(GetTopRator(op),ch))
{
PushRator(op,ch);
ch = getchar();
}
else
{
PopRand(ra,&b);
PopRand(ra,&a);
PopRator(op,&s);
PushRand(ra,Calculation(a,b,s));
}
}
}
}
printf("运算结果为%d\n",GetTopRand(ra));
return 0;
}
在main.c文件中使用了一个死循环while(1),执行一次程序可以计算多个算式,在要最后一次输入算式时以#~结尾即可结束程序
main.c
#include <stdio.h>
#include <stdlib.h>
#include "Evaluation.h"
#include "Evaluation.c"
int main()
{
InitOperand(&operands);
InitOperator(&operators);
while(1)
{
char ch;
ExpCalculation(&operands,&operators);
EmptyRand(&operands);
EmptyRator(&operators);
ch = getchar();
if(ch == '~') //在输入要运算的算式时,在#后面输入~来退出循环结束程序
exit(0);
}
return 0;
}
括号可以嵌套使用,在运行程序输入算式时要注意不要输入中文括号,否则计算结果可能会出现错误。