用C语言实现字符串转表达式并计算结果
原理:用栈操作将中缀表达式转换为后缀表达式,再将后缀表达式计算。(需要特别注意运算符的优先级)。
中缀转后缀:读到操作数时,将其放到输出中,操作符用栈保存,特别注意运算符的优先级。(详细原理可查阅资料)
后缀计算:将读到的操作数保存到栈,读到操作符时将栈中两个操作数出栈,并与该操作符进行运算,再将计算结果压栈,特别要注意需要做好错误处理。
注意:栈可分别建立一个数据栈和一个操作符栈。该程序支持小数 整数 科学计数法 ,运算符支持+ - * / 幂(^)需要其他操作可在此基础上添加。
需要详细说明可留言或评论区讨论。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define STACK_SIZE 512
typedef enum ElemDataType
{
OPERATOR = 1,
INT,
DOUBLE,
POINTER
} ElemDataType;
typedef struct StackElem
{
ElemDataType type;
union {
char op;
int i;
double d;
void *p;
};
} ElemType;
ElemType elemFromOperator(char c)
{
ElemType ret = {
.type = OPERATOR, .op = c};
return ret;
}
ElemType elemFromInt(int i)
{
ElemType ret = {
.type = INT, .i = i};
return ret;
}
ElemType elemFromDouble(double d)
{
ElemType ret = {
.type = DOUBLE, .d = d};
return ret;
}
ElemType elemFromPointer(void* p)
{
ElemType ret = {
.type = POINTER, .p = p};
return ret;
}
// ADT: Expression
//==================================================================
typedef struct Expression
{
int size;
int capacity; // 容量
ElemType *tokens;
} Expression;
void initExpression(Expression *pExpr)
{
if (pExpr == NULL)
{
return;
}
pExpr->size = 0;
pExpr->capacity = 10;
pExpr->tokens = malloc(sizeof(ElemType) * pExpr->capacity);
}
// 扩容
void expandExpression(Expression *pExpr, int newCapcity)
{
if (pExpr == NULL)
{
return;
}
if (newCapcity <= pExpr->capacity * 2)
{
newCapcity = pExpr->capacity * 2;
}
ElemType* newTokens = malloc(sizeof(ElemType) * newCapcity);
memcpy(newTokens, pExpr->tokens, sizeof(ElemType) * pExpr->capacity);
free(pExpr->tokens);
pExpr->tokens = newTokens;
}
void appendToken(Expression *pExpr, ElemType elem)
{
if (pExpr == NULL)
{
return;
}
if (pExpr->size == pExpr->capacity)
{
expandExpression(pExpr, 0);
}
pExpr->tokens[pExpr->size] = elem;
pExpr->size ++;
}
void clearExpression(Expression *pExpr, ElemType type)
{
if (pExpr == NULL)
{
return;
}
pExpr->size = 0;
}
void freeExpression(Expression *pExpr)
{
if (pExpr == NULL || pExpr->tokens == NULL)
{
return;
}
free(pExpr->tokens);
pExpr->tokens = NULL;
pExpr->size = 0;
}
// ADT: Stack
//==================================================================
struct Stack
{
ElemType datas[STACK_SIZE];
int top;