逆波兰表达式求值 C语言

输入一个表达式字符串,如1+34-6,输出这个表达式的值.要求至少实现正整数的加减乘除四则运算,如100- 54 -50/10 =75

不懂栈结构的,可以去看我的另一篇文章,有关于压栈、出栈的基本代码
用到了两个栈,数据压入数据栈内,运算符压入符号栈内

提示:需要建立两个栈结构,一个为整形存放操作数,另一个为字符型,存放运算符,运算符的进栈要和在站顶的元素比较优选级如果低于栈顶元素则进行一次运算

/*
* 
* 逆波兰表达式的应用
* 加减乘除(不包含括号及复杂运算)的运算
* 输入正确格式的字符串
* 输出结果
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 20
int number_stack[MAXSIZE];
char opera_stack[MAXSIZE];
int number_ptr = 0;
int opera_ptr = 0;
void number_push_stack(int n);    //数据栈入栈
void opera_push_stack(char c);   //符号栈入栈
int  number_pop_stack();			//数据栈出栈
char opera_pop_stack();				//符号栈出栈
int opera_proprity(char c);         //传参运算符,返回运算符的优先级
int opera_result(char c, int number1, int number2);   //传参操作符和两个操作数,返回运算结果
int movecount(int number);     辅助string_ptr移动位数函数(根据字符串转换的数字number)
void number_push_stack(int n)
{
	if (number_ptr > MAXSIZE - 1)
	{
		fprintf(stderr, "数字栈已满!\n");
		return;
	}
	number_stack[number_ptr++] = n;
	printf("%d数字已入栈,当前剩余容量为:%d\n", n, MAXSIZE - number_ptr);
}
void opera_push_stack(char c)
{
	if (opera_ptr > MAXSIZE - 1)
	{
		fprintf(stderr, "符号栈已满!\n");
		return;
	}
	opera_stack[opera_ptr++] = c;
	printf("%c符号已入栈,当前剩余容量为:%d\n", c, MAXSIZE - opera_ptr);
}
int  number_pop_stack()
{
	int number;
	if (number_ptr < 0)
	{
		fprintf(stderr, "数字栈已空!\n");
		return -1;
	}
	number = number_stack[--number_ptr];
	printf("%d数字已出栈,当前剩余容量为:%d\n", number, MAXSIZE - number_ptr);
	return number;

}
char opera_pop_stack()
{
	char c;
	if (opera_ptr < 0)
	{
		fprintf(stderr, "符号栈已空\n");
		return -1;
	}
	c = opera_stack[--opera_ptr];
	printf("%c符号已出栈,当前剩余容量为:%d\n", c, MAXSIZE - opera_ptr);
	return c;
}
int movecount(int number)   //通过传入的数字,判断处理当前字符串的模拟指针应向后移动几位
{
	int count = 0;
	while (number != 0)
	{
		number = number / 10;
		count++;
	} 
	return count;
}
int opera_proprity(char c)  //运算符优先级判断函数
{
	if (c == '/' || c == '*')
		return 2;
		//printf("2\n");
	else
		return 1;
		//printf("1\n");
}
int opera_result(char c, int number1, int number2)//通过传入的运算符和两个操作数,返回结果
{
	if (c == '+')
		return number1 + number2;
	if (c == '-')
		return number1 - number2;
	if (c == '*')
		return number1 * number2;
	if (c == '/')
		return number1 / number2;
}
int main()
{
	int length;
	char str[100];
	printf("请输入算术表达式(目前仅支持加减乘除,格式请务必正确!):");
	fgets(str, 100, stdin);
	length = strlen(str);
	if (length < 99)
	{
		str[length - 1] = 0;
		length--;    //去除fgets函数添加的\n
	}
	//char number_string[15];       //存放转为整型数字的字符串
	int string_ptr = 0;       //指向当前处理到的字符串的位置
	int string_ptr_move = 0;  //辅助string_ptr移动多少位
	int string_number = 0;       //字符串转换整型数字
	char c;					//一定条件下赋予栈顶运算符进行运算	
	int number1, number2;   //一定条件下,数据栈出栈进行运算的两个操作数
	int result = 0;           //存储最终运算结果与临时运算结果

	while (1)								//这里处理运算符和操作数的入栈,若操作符入栈过程
											//中出现优先级高低的问题,还得进行出栈运算后然后结果入栈处理
	{
		string_number = atoi(str + string_ptr);
		number_push_stack(string_number);
		string_ptr_move = movecount(string_number);
		string_ptr = string_ptr + string_ptr_move;  //数组模拟数据指针的移动
		if (string_ptr == length) break;       //读到最后一个数字之后时,为'\0'结束符,直接退出
		if (opera_ptr > 0 && (opera_proprity(opera_stack[opera_ptr - 1]) > opera_proprity(str[string_ptr])))//将运算符栈栈顶元素优先级与要压入的运算符
		{																				//的优先级做对比,若要压入的运算符的优先级更小,则先弹出
			number1 = number_pop_stack();												//栈顶运算符进行运算后再进行压栈
			number2 = number_pop_stack();												//当运算符栈为空时,不进行对比并运用到了短路原则
			c = opera_pop_stack();
			number1 = opera_result(c, number2, number1);   //number1重用,少声明其他中间变量,注意number1,number2的前后顺序
			number_push_stack(number1);
		}
		opera_push_stack(str[string_ptr++]);   //这里犯了一次错误,存了下标,应该存下标所在的数组值

	}
	while (number_ptr != 0 && opera_ptr != 0)
	{
		c = opera_pop_stack();
		if (opera_proprity(c) == 2)            //若操作符存在乘除,则进行特殊处理
		{
			number1 = number_pop_stack();
			number2 = number_pop_stack();
			number1 = opera_result(c, number2, number1);
			number_push_stack(number1);
		}
		else
		{
			number1 = number_pop_stack();
			number1 = opera_result(c, 0, number1);
			result += number1;
		}

	}
	result += number_pop_stack();      //加上栈底的最后一个数
	printf("结果为:%d", result);

	return 0;
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值