//#pragma once
#define _CRT_SECURE_NO_WARNINGS 1//是一个预处理指令,用于禁止编译器报告关于不安全函数的警告。如果没有该指令就会导致下面的strcpy函数无法运行
//strcpy函数的作用:处于string.h的头文件中,作用是拷贝字符串,即复制,strcpy(str1,str2)将str2中的字符复制给str1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 定义最大栈大小和字符串长度
#define MaxSize 10
#define MaxString 100
// 定义栈数据类型为字符
typedef char STType;
// 定义栈结构体,包含数据数组、栈顶索引和容量
typedef struct Stack
{
STType* a;// 指向栈存储空间的指针
int top; // 栈顶元素索引,栈为空时top为-1
int Maximum_capacity; // 栈的最大容量
}STACK;
//初始化
void StackInit(STACK* ps);
//销毁
void StackDestroy(STACK* ps);
//压栈
void StackPush(STACK* ps, STType x);
//弹栈
void StackPop(STACK* ps);
//读取栈顶元素
STType StackTop(STACK* ps);
//读取栈中元素个数
int StackSize(STACK* ps);
//判空
bool StackEmpty(STACK* ps);
// 初始化栈,分配内存空间
void StackInit(STACK* ps)
{
ps->a = (STType*)malloc(sizeof(STType) * (MaxSize));
ps->Maximum_capacity = MaxSize;
ps->top = 0;
}
// 压栈操作,如果栈满则扩容
void StackPush(STACK* ps, STType x)
{
if (ps->Maximum_capacity == ps->top)
{
ps->a = (STType*)realloc(ps->a, sizeof(STType) * (2 * ps->Maximum_capacity));
ps->Maximum_capacity *= 2;
if (ps->a == NULL)
{
return;
}
}
ps->a[ps->top] = x;
ps->top++;
}
//弹栈操作
void StackPop(STACK* ps)
{
if (ps->top == 0)
{
return;
}
ps->top--;
}
//获取栈顶元素的值
STType StackTop(STACK* ps)
{
STType x = ps->a[ps->top - 1];
return x;
}
// 销毁栈,释放内存空间
void StackDestroy(STACK* ps)
{
if (ps->a)
{
free(ps->a);
ps->a = NULL;
ps->Maximum_capacity = 0;
ps->top = 0;
}
}
//获取栈顶元素的数量
int StackSize(STACK* ps)
{
return ps->top;
}
//检查栈是否为空
bool StackEmpty(STACK* ps)
{
return (ps->top == 0);
}
//计算后缀表达式的值
int calPostfix(char* str)
{
STACK numsStack;
StackInit(&numsStack);
for (int i = 0; i < (int)strlen(str); i++)
{
if (str[i] >= '0' && str[i] <= '9')
{
int x = str[i] - '0';
StackPush(&numsStack, x);
}
else
{ //x左操作数
int x = StackTop(&numsStack);
StackPop(&numsStack);
//y右操作数
int y = StackTop(&numsStack);
StackPop(&numsStack);
switch (str[i])
{
case '+':
x += y;
break;
case '-':
x -= y;
break;
case '*':
x *= y;
break;
case '/':
x /= y;
break;
}
StackPush(&numsStack, x);
}
}
return StackTop(&numsStack);
}
//比较操作符优先级
int compare(char ch)//用void则会导致不合法则
{
if (ch == '+' || ch == '-')
{
return 1;
}
else if (ch == '*' || ch == '/')
{
return 2;
}
else if (ch == '(' || ch == ')')
{
return 0;
}
else
{
return -1;
}
}
//将中缀表达式转换成后缀表达式
char* postfixNotation(char* str)
{
//results保存结果,Provisional_operator临时保存操作符
STACK results;
STACK Provisional_operator;
StackInit(&results);//初始化results栈
StackInit(&Provisional_operator);//初始化provisional_operator栈
for (int i = 0; i < (int)strlen(str); i++)
{//如果当前字符被compare函数判断为数字的话,则直接压入results栈
if (compare(str[i]) == -1)
{
StackPush(&results, str[i]);
}
//如果当前字符是左括号,则直接将其压入Provisional_operator栈中
else if (str[i] == '(')
{
StackPush(&Provisional_operator, str[i]);
}
else if (str[i] == ')')//遇到右括号直接弹出Provisional_operator栈直到遇到左括号
{
//只要provisional_operator栈的栈顶不是左括号
while (StackTop(&Provisional_operator) != '(')
{
//则获取栈顶元素并存入变量x
char x = StackTop(&Provisional_operator);
//将栈顶元素压入results栈
StackPush(&results, x);
//弹出Provisional_operator栈的栈顶元素
StackPop(&Provisional_operator);
}
//弹出Provisional_operator栈的左括号
StackPop(&Provisional_operator);
}
//如果当前字符是其他操作符号时
else
{
//如果Provisional_operator栈不为空,则其栈顶操作符的优先级大于等于当前操作符
if (!StackEmpty(&Provisional_operator) && compare(StackTop(&Provisional_operator)) >= compare(str[i]))
{
//只要Provisional_operator栈不为空,且其栈顶操作符的优先级大于等于当前操作符
while (!StackEmpty(&Provisional_operator) && compare(StackTop(&Provisional_operator)) >= compare(str[i]))
{
//获取Provisional_operator栈的栈顶元素并存入变量x
char x = StackTop(&Provisional_operator);
//弹出Provisional_operator栈的栈顶元素
StackPop(&Provisional_operator);
//将栈顶元素压入results栈
StackPush(&results, x);
}
//将当前操作符压入Provisional_operator栈栈
StackPush(&Provisional_operator, str[i]);
}
//如果Provisional_operator栈为空或者其栈顶操作夫的优先级小于当前操作符
else
{
//将当前操作符号压入Provisional_operator栈
StackPush(&Provisional_operator, str[i]);//将操作符压入S2
}
}
}
//只要Provisional_operator栈不为空
while (!StackEmpty(&Provisional_operator))
{
//获取Provisional_operator栈的栈顶元素并存入变量x
char x = StackTop(&Provisional_operator);
//将栈顶元素压入results栈
StackPush(&results, x);
//弹出Provisional_operator栈的栈顶元素
StackPop(&Provisional_operator);
}
//在results栈的末尾添加字符串结束符
StackPush(&results, '\0');//在S1末尾添加字符串结束符
//返回results栈的内容
return (char*)results.a;
}
int main()
{
printf("请输入中缀表达式(无需等号):");
char str[MaxString];
gets(str);
strcpy(str, postfixNotation(str));
printf("转换的后缀表达式为:%s\n", str);
int ret = calPostfix(str);
printf("结果为:%d\n", ret);
return 0;
}
简易计算器
最新推荐文章于 2024-09-30 10:07:25 发布