xdoj前缀表达式求值

此题的求解过程基本和后缀表达式一致(可以看一下我的“xdoj后缀表达式”),难点之一就是处理输入的字符串,我选择将整个字符串全部读入,然后根据空格的分隔来处理字符串。

我采用了

	scanf("%[^\n]", str);

的语句,便可以将空格读入字符串,一般的scanf("%s", str)在遇到空格,也就是 '0' 和回车 也就是

 '\n'时会停止读入。

将整个语句读入之后去根据空格的分隔去处理,其中有两个问题,一是对于多位整数

我采用了

do
{
	a = a * 10 + (str[i] - '0');
	i++;
} while (str[i] != ' ' && str[i] != '\0');

使用do while循环可以省去个位数的情况的判断,无论是几位数都先将第一位数字赋给a,而当是多位数时,原本的a需要进一位,十进制就是乘十了。

第二个问题在于后续计算时,如何判断运算符是运算符,对于上一道题,后缀表达式,题目中说明了是个位数的计算,而加减乘除的符号对应的Ascll码值分别为43,45,42,47,故而可以直接使用 S->data == '+' 来判断,但是对于此题,其中运算的整数并没有特殊说明,甚至在oj中的例子里的42就是 * 的Ascll码值,42 == '/' , 返回的是1。

对此,我采用了在链栈的数据中新加一标志符flag, 当压栈时,数字字符仍是0-9,此时就可以用==来判断运算符,如果确是运算符,就使其为1,后面运算的时候就可以是双重判断,即

S->data == '+' && S->flag == 1,来确定是运算符。

以下是代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct STNode
{
	int data;
	int flag;
	struct STNode* next;
}STNode, * LinkStack;

void Push(LinkStack* S, int e);
int Pop(LinkStack* S);

int main()
{
	char str[100];
	int i, j;
	LinkStack S = NULL;
	LinkStack Q = NULL;
	int a = 0;
	scanf("%[^\n]", str);
	for (i = 0; i < strlen(str);)
	{
		if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
		{
			Push(&S, str[i]);
			S->flag = 1;
			i++;
		}
		else if (str[i] >= '0' && str[i] <= '9')
		{
			do
			{
				a = a * 10 + (str[i] - '0');
				i++;
			} while (str[i] != ' ' && str[i] != '\0');
			Push(&S, a);
			S->flag = 0;
			a = 0;
		}
		else
		{
			i++;
		}
	}
	while (S != NULL)
	{
		if (S->data == '+' && S->flag == 1)
		{
			Push(&Q, Pop(&Q) + Pop(&Q));
			Pop(&S);
		}
		else if (S->data == '-' && S->flag == 1)
		{
			Push(&Q, Pop(&Q) - Pop(&Q));
			Pop(&S);
		}
		else if (S->data == '*' && S->flag == 1)
		{
			Push(&Q, Pop(&Q) * Pop(&Q));
			Pop(&S);
		}
		else if (S->data == '/' && S->flag == 1)
		{
			Push(&Q, Pop(&Q) / Pop(&Q));
			Pop(&S);
		}
		else
		{
			Push(&Q, Pop(&S));
		}
	}
	printf("%d", Q->data);
	return 0;
}

void Push(LinkStack* S, int e)
{
	LinkStack q = (LinkStack)malloc(sizeof(STNode));
	q->next = (*S);
	q->data = e;
	(*S) = q;
}

int Pop(LinkStack* S)
{
	LinkStack q = (*S);
	int e = q->data;
	(*S) = (*S)->next;
	free(q);
	return e;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值