首页 > 其他 > 详细

程序设计II第二次实验题—逆逆波兰式解题思路(后辍转中辍)

时间:2021-04-13 17:12:43      阅读:26      评论:0      收藏:0      [点我收藏+]

   2021-04-13

   10:46:27

A、逆逆波兰式

贡献者程序设计2
提交情况
4 / 5

题目描述

Time limit: 1000 ms
Memory limit: 256 MB
Standard I/O

仔细学习老师关于“递归”的ppt之后,你学会了如何将一个逆波兰式转换回原本的表达式;只是,有些时候,你会输出大量多余的括号。
这次,我们仍旧要将一个逆波兰式转换回一个正常的表达式—— 但不能输出任何多余的括号 。

【警告】可以使用栈,但不允许使用C++的std::stack

【逆逆波兰式】题面中的“多余”说明:https://git.ustc.edu.cn/programming-ii-spring2021/DiscussionBoard/-/issues/15

输入描述

输入有且只有一行,行末回车符前只会出现“+”“-”“*”“/”和数字“0”到“9”;数字至少出现一次,每一个数字代表一个单独的数值(原表达式和逆波兰式中的数都是一位数)。

输出描述

输出包括一行,为输入逆波兰式对应的原表达式,但不能有任何 多余的括号 !

样例输入

123++

样例输出

1+(2+3)

样例输入

12+3+

样例输出

1+2+3

样例输入

12+34+*

样例输出

(1+2)*(3+4)

样例输入

123*+

样例输出

1+2*3

样例解释

题意解读:

    我们平时所使用的式子为中辍表达式,而逆波兰表达式也是后辍表达式,通过把运算符后置来实现括号等形式的简化。同理,波兰表达式是前辍表达式,我们在这里只讨论逆波兰表达式。

逆波兰表达式很好的满足递归关系:

1.一个数字本身即是一个逆波兰表达式

2.数字+数字+运算符=逆波兰表达式

3.逆波兰表达式+逆波兰表达式=逆波兰表达式

解题思路1(递归函数版)

通过递归程序及优先级参数来确定所对应的中辍表达式以及括号的有无。

在这里,我们通过构造exchange函数来实现这个功能。

string exchange(string str, int order)//str为输入字符串,order为优先级参数
{
	while ( l-- && l >= 0)//l为字符串长度,此句为递归终止条件判定
	{
		if (str[l] == ‘+‘)
		{
			if (order <= 0)
				return exchange(str, 0) + ‘+‘ + exchange(str, 1);
			else
				return ‘(‘ + exchange(str, 0) + ‘+‘ + exchange(str, 1) + ‘)‘;
		}
		else if (str[l] == ‘-‘)
		{
			if (order <= 0)
				return exchange(str, 0) + ‘-‘ + exchange(str, 1);
			else
				return ‘(‘ + exchange(str, 0) + ‘-‘ + exchange(str, 1) + ‘)‘;
		}
		else if (str[l] == ‘*‘)
		{
			if (order <= 1)
				return exchange(str, 1) + ‘*‘ + exchange(str, 2);
			else
				return ‘(‘ + exchange(str, 1) + ‘*‘ + exchange(str, 2) + ‘)‘;
		}
		else if (str[l] == ‘/‘)
		{
			if (order <= 1)
				return exchange(str, 1) + ‘/‘ + exchange(str, 2);
			else
				return ‘(‘ + exchange(str, 1) + ‘/‘ + exchange(str, 2) + ‘)‘;
		}
		else
		{
			string s;
			s.push_back(str[l]);
			return s;
		}
	}

  解题思路2(纯列举法)

    同上一样,通过构造exchange函数,不过此方法多使用char型字符数组和结构体进行操作,灵感来源于他人。

此处构造结构体来实现对输入字符串,输出字符串的统一。

typedef struct
{
	char str1[MAX_LENGTH];
	char sign[MAX_NUM];
	char str2[MAX_LENGTH];
} TREE;

  然后......比较复杂,先贴代码,读者可自行理解,后续补充思路

void exchange()
{
	int i = 0;
	char a[100], temp[100];
	scanf("%s", a);
	for (i = 0; a[i] != ‘\0‘; i++)
	{
		switch (a[i])
		{
		case ‘+‘:
		case‘-‘:
			//If only the first member of the penultimate structure stores information, 
			//there is no need to push the information of the other two members into
			if (list[num - 2].sign[0] != ‘\0‘)
			{

				strcpy(temp, list[num - 2].str1);
				strcat(list[num - 2].str1, list[num - 2].sign);
				strcat(list[num - 2].str1, list[num - 2].str2);

			}
			list[num - 2].sign[0] = a[i];//Add operator
			if (list[num - 1].sign[0] != ‘\0‘)
			{
				if (list[num - 1].sign[0] == ‘*‘ || list[num - 1].sign[0] == ‘/‘)
				{
					strcpy(list[num - 2].str2, list[num - 1].str1);
					strcat(list[num - 2].str2, list[num - 1].sign);
					strcat(list[num - 2].str2, list[num - 1].str2);
				}
				else
				{
					////Add parentheses to ensure priority
					strcpy(list[num - 2].str2, "(");
					strcat(list[num - 2].str2, list[num - 1].str1);
					strcat(list[num - 2].str2, list[num - 1].sign);
					strcat(list[num - 2].str2, list[num - 1].str2);
					strcat(list[num - 2].str2, ")");
				}
			}
			else
			{
				strcpy(list[num - 2].str2, list[num - 1].str1);
			}
			memset(&list[num - 1], 0, sizeof(TREE));

			num--;
			break;

		case ‘/‘:
		case ‘*‘:
			//If only the first member of the penultimate structure stores information, 
			//there is no need to push the information of the other two members into
			if (list[num - 2].sign[0] != ‘\0‘)
			{
				if (list[num - 2].sign[0] == ‘*‘ || list[num - 2].sign[0] == ‘/‘)
				{

					strcat(list[num - 2].str1, list[num - 2].sign);
					strcat(list[num - 2].str1, list[num - 2].str2);
				}
				else//Add parentheses to ensure priority
				{
					strcpy(temp, list[num - 2].str1);
					strcpy(list[num - 2].str1, "(");
					strcat(list[num - 2].str1, temp);
					strcat(list[num - 2].str1, list[num - 2].sign);
					strcat(list[num - 2].str1, list[num - 2].str2);
					strcat(list[num - 2].str1, ")");
				}
			}
			list[num - 2].sign[0] = a[i];
			if (list[num - 1].sign[0] != ‘\0‘)
			{
				//Add parentheses to ensure priority
				strcpy(list[num - 2].str2, "(");
				strcat(list[num - 2].str2, list[num - 1].str1);
				strcat(list[num - 2].str2, list[num - 1].sign);
				strcat(list[num - 2].str2, list[num - 1].str2);
				strcat(list[num - 2].str2, ")");
			}
			else
			{
				strcpy(list[num - 2].str2, list[num - 1].str1);
			}
			//Clear the variable information of the first to last structure
			memset(&list[num - 1], 0, sizeof(TREE));
			num--;
			break;
		default:
			list[num].str1[0] = a[i];
			list[num].str1[1] = ‘\0‘;
			num++;
			break;

		}
	}
	//All information is pushed into the first structure member
	printf("%s", list[0].str1);
	if (list[0].sign[0] != ‘\0‘)
	{
		printf("%c", list[0].sign[0]);
	}
	printf("%s", list[0].str2);
}

  

解题思路3(栈版)后续补充

 

 

如有其他思路及更好理解,欢迎与我沟通交流。

程序设计II第二次实验题—逆逆波兰式解题思路(后辍转中辍)

原文:https://www.cnblogs.com/zzx6869/p/14652131.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!