c语言- -数据结构- -实现逆波兰式(中缀表达式转为后缀表达式)

思路

8be95319f73747b49fe690cb0deef7da.png

详细设计:

A.存储结构:

表达式都是由一个个字符组成的,所以采用char类型的数组来保存中缀表达式和后缀表达式。

由于运算符是有优先级的,乘法,除法,加法,减法计算都是有先后顺序的,由于栈的特性与之相契合,所以用一个数据栈来暂时保存运算符,然后在最后输出运算符。

B.算法的详细设计:

         循环结构:最外层嵌套一个大循环,使得中缀表达式里的每一个字符都得以遍历

   条件语句:考虑到每一类优先级,还要注意前一个字符与当前字符之间的隐藏关系

   字符的传递:栈与两个数组之间的,数组和数组之间的互相赋值问题

 

//逆波兰式(中缀表达式转化为后缀表达式)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<assert.h>
#define SIZE 100
char* MidToLast(const char* str)
{
	int len = (int )strlen(str);//获取中缀表达式长度
	char* last = (char*)malloc(len * 2);//后缀表达式数组
	assert(last != NULL);
	char crr[SIZE];//栈
	int i = 0;//中缀表达式数组下标
	int k = 0; //栈下标
	int pos = 0;//后缀表达式数组下标
	for ( ;str[i] != '\0'; i++)
	{
		if (str[i] <= '9' && str[i] >= '0')//数字直接放在后缀表达式数组里
		{
			if (i > 0&& last[pos - 1] <= '9' && last[pos - 1] >= '0')
			{
				last[pos] = ' ';
				pos++;
			}
			if (str[i - 1] <= '9' && str[i - 1] >= '0')
			{
				pos--;
			}
			last[pos] = str[i];
			pos++;
		}
		if (str[i] == '*'||str[i]=='/')//入栈
		{
			crr[k] = str[i];
			k++;
		}
		if (str[i] == '+' || str[i] == '-')
		{
			if (k > 0)
			{
				if (crr[k - 1] == '*' || crr[k - 1] == '/')
//'*', '\' 的优先级高,先出栈再入栈
				{
					last[pos] = ' ';
					pos++;
					last[pos] = crr[k - 1];//出栈
					pos++;
					crr[k - 1] = str[i];//入栈
				}
				else
				{
					crr[k] = str[i];//同为'+' '-',优先级相同直接入栈
					k++;
				}
			}
			else
			{
				crr[k] = str[i];
				k++;
			}
		}
		if (str[i] == ' ')//中缀表达式中所有的空格不做处理
		{
			;
		}
	}
	while (k > 0)//把栈里面的运算符输出到外面
	{
		last[pos] = ' ';//为了美观,给每一个字符之间加一个空格
		pos++;
		last[pos]=crr[k-1];//赋值
		k--;
		pos++;
	}
	last[pos] = '\0';//必须在最后赋值以‘\0’,防止输出错误
	return last;//返回已经存储好的后缀表达式
}
int main()
{
	char str[SIZE] = "12*1 + 12 ";
	printf(" %s 的后缀表达式: %s\n",str, MidToLast(str));
	return 0;
}

总结

        在完成一个课题设计时,第一步是搞清楚题目的含义,比如逆波兰式,这个表达式要深刻理解,才可以进行算法代码。了解含义后,根据所学知识选用合适的存储结构和算法思路。先有思路,再进行算法思路的整理和设计,最后代码编写就会行云流水,最最后就是调试,在此期间一定要有足够的耐心,慢慢思考,慢慢检查,看看代码的中英文转化是否正确,看看逻辑是否出问题,或者在哪一方面还没有思考周全,最后一定会调试出来的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值