思路:
遍历中缀表达式中的数字和符号:
对于数字:直接输出
对于符号:
左括号:进栈
运算符号:与栈顶符号进行优先级比较
左括号:进栈
运算符号:与栈顶符号进行优先级比较
若栈顶符号优先级低:此符号进栈(默认栈顶若是左括号,左括号优先级最低)
若栈顶符号优先级不低;将栈顶符号弹出并输出,之后进栈
右括号:将栈顶符号弹出并输出,直到匹配左括号
遍历结束:将栈中的所有符号弹出并输出
后缀表达式计算
遍历后缀表达式中的数字和符号
对于数字:进栈
对于符号:
从栈中弹出右操作数
从接中弹出左操作数
根据符号进行运算
将运算结果压入栈中
遍历结束:栈中的唯一数字为计算结果
8+(3-1)*5的计算
Infix_Variable_Suffix.h
#define _CRT_SECURE_NO_WARNINGS
#include "Chain_Stack.h"
#include <ctype.h>
//转换
int priority(char c);
void output(char c);
bool is_Left(char c);
bool is_Right(char c);
bool isOperator(char c);
void transform(const char* exp);
//计算
int express(int left, int right, char op);
int* Value(char c);
int compute(const char*exp);
char str[10] = { 0 };
char *buff = str;
int *arr[100] = { 0 };
int count = 0;
.cpp
#include "Infix_Variable_Suffix.h"
//转换
int priority(char c)
{
int ret = 0;
if (c == '+' || c == '-')
{
ret = 1;
}
if (c == '*' || c == '/')
{
ret = 2;
}
return ret;
}
void output(char c)
{
if (c != '\0')
{
printf("%c", c);
sprintf(buff++, "%c", c);
}
}
bool is_Left(char c)
{
return c == '(';
}
bool is_Right(char c)
{
return c == ')';
}
bool isOperator(char c)
{
return (c == '+') || (c == '-') || (c == '*') || (c == '/');
}
void transform(const char *exp)
{
assert(exp != NULL);
int i = 0;
LinkStack *stack = LinkStack_Create();
while (exp[i] != '\0')
{
if (isdigit(exp[i]))//直接输出数字
{
output(exp[i]);
}
else if (isOperator(exp[i])) //操作符入栈
{
if (LinkStack_Top(stack) != NULL)
{
while (priority(exp[i]) <= priority(*(char*)LinkStack_Top(stack)))
{
output(*(char*)LinkStack_Pop(stack));
}
LinkStack_Push(stack, (void*)(exp + i));
}
else
{
LinkStack_Push(stack, (void*)(exp + i));
}
}
else if (is_Left(exp[i])) //左括号入栈
{
LinkStack_Push(stack, (void*)(exp + i));
}
else if (is_Right(exp[i]))
{
while (!is_Left(*(char*)LinkStack_Top(stack)))
{
output(*(char*)LinkStack_Pop(stack));
}
LinkStack_Pop(stack); //左括号出栈
}
else
{
printf("Invalid expression!");
break;
}
i++;
}
while (LinkStack_Size(stack) > 0 && exp[i] == '\0')
{
output(*(char*)LinkStack_Pop(stack));
}
printf("\n");
LinkStack_Destroy(stack);
}
//计算
int express(int left, int right, char op)
{
int ret = 0;
switch (op)
{
case '+':
ret = left + right;
break;
case '-':
ret = left - right;
break;
case '*':
ret = left*right;
break;
case '/':
ret = left / right;
break;
default:
break;
}
return ret;
}
int* Value(char c)
{
int *a = (int*)malloc(sizeof(int));
*a = c - '0';
arr[count++] = a;
return a;
}
int compute(const char*exp)
{
LinkStack *stack = LinkStack_Create();
int i = 0;
while (exp[i] != '\0')
{
if (isdigit(exp[i])) //数字直接入栈
{
LinkStack_Push(stack, (void*)Value(exp[i]));
}
else if (isOperator(exp[i])) //如果是运算符,从栈中提取两个数
{
int right = *(int*)LinkStack_Pop(stack);
int left = *(int*)LinkStack_Pop(stack);
int result = express(left, right, exp[i]);
LinkStack_Push(stack, (void*)&result); //计算结果入栈
}
else
{
printf("Invalid expression!");
break;
}
i++;
}
int ret = 0;
if (LinkStack_Size(stack) == 1 && exp[i] == '\0')
{
ret = *(int*)LinkStack_Pop(stack);
}
else
{
printf("Invalid expression!");
}
LinkStack_Destroy(stack);
return ret;
}
main.cpp
int main()
{
transform("8+(3-1)*5");
int result = compute(str);
printf("%d\n", result);
for (int i = 0; i < count; i++)
{
free(arr[i]);
}
_CrtDumpMemoryLeaks();
system("pause");
return 0;
}