简易计算器

//#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值