02-线性结构3. 求前缀表达式的值(25)

/*
求前缀表达式的值
pat Mooc ds
by zhoudaxia
*/

#include<stdio.h>
#include<stdlib.h>

//栈的基本操作
typedef struct node *Stack;
typedef double ElementType;
struct node{
	ElementType Element;
	struct node *next;
};

int
isEmpty(Stack S)
{
	return S->next == NULL;
}

ElementType
pop(Stack S)
{
	if(isEmpty(S))
		printf("Stack is empty");
	else
	{
		Stack tmpS;
		ElementType tmpE;
	 	tmpS = S->next;
		S->next = tmpS->next;
		tmpE = tmpS->Element;
		free(tmpS);
		//不能return S->next->Element 因为S可能为空
		return tmpE;
	}
}	

void
MakeEmpty(Stack S)
{
	if(S == NULL)
		printf("Use CreateStack first");
	else
		while(!isEmpty(S))
			pop(S);
}

Stack
CreateStack()
{
	Stack tmpS;
	tmpS = (struct node*)malloc(sizeof(struct node));
	if(tmpS == NULL)
		printf("Out of Space");
	tmpS->next = NULL;
	MakeEmpty(tmpS);
	return tmpS;
}

void
push(Stack S,ElementType X)
{
	Stack tmpS;
	tmpS = (struct node*)malloc(sizeof(struct node));
	tmpS->Element = X;
	tmpS->next = S->next;
	S->next = tmpS;
}

int
isOperator(double c)
{
	return (c==(double)'+'||c==(double)'-'||c==(double)'*'||c==(double)'/');
}

double
ComputeTwo(double c1,double c2,double operator)
{
	double result;
	switch((int)operator)
	{
	  case '+': result = c1+c2;break;
	  case '-': result = c1-c2;break;
	  case '*': result = c1*c2;break;
	  case '/': result = c1/c2;break;
	}
	return result;
}

//根据字符串的不同,将字符串变成数字
double
getNum(char s[])
{
	int i = 0;
	int j = 0;
	double sum = 0;
	double chu =1;
	double sum_d = 0;
	for(i = 0; i != strlen(s);++i)
		if(*(s+i)=='.')
			break;
	if(i == strlen(s))			//没有小数点
	{
		if(*s=='+'||*s=='-')		//起始有符号位,则j从1开始
			j++;
		for(; j != strlen(s); ++j)
			sum = 10*sum + *(s+j)-'0';
		if(*s=='-')
			sum = -sum;
	}
	else
	{
		if(*s=='+'||*s=='-')
			j++;
		for(; j != i ; ++j)
			sum = 10 * sum + *(s+j)-'0';
		for(j = i+1; j != strlen(s); ++j)
			{
			chu = chu*10;
			sum_d = sum_d + (*(s+j)-'0')/chu;
			}
		sum = sum +sum_d;
		if(*s=='-')
			sum = -sum;
	}
	return sum;
}
int main()
{
	double c[30],c1,c2;
	char s[30];
	int i=0;
	int j;
	double exp = 0;		//save the value of the expression
	Stack S;
	S = CreateStack();
	while(scanf("%s",s)!=EOF)
		{
		if(strlen(s)==1)
			{if(*s=='+'||*s=='-'||*s=='*'||*s=='/')
				c[i]=(double)(*s);
			else
				c[i]=(double)(*s-'0');
			}
		else
			c[i] = getNum(s);	
		++i;			
		}	
	--i;			//关键
	for(j=i; j!=-1; --j)
	{
	//	printf("%c",c[j]);
		if(!isOperator(c[j]))
			push(S,c[j]);
		else
		{
			c1 = pop(S);
			c2 = pop(S);
			if(c[j]=='/'&&c2==0)
				{
					printf("ERROR");
					return 0;
				}
				
			push(S,ComputeTwo(c1,c2,c[j]));
		}
	}
	exp = pop(S);
	
	printf("%.1f",exp);
	return 0;
}



序号 输入 输出
1
+ + 2 * 3 - 7 4 / 8 4
13.0
2
/ -25 + * - 2 3 4 / 8 4
12.5
3
/ 5 + * - 2 3 4 / 8 2
ERROR
4
+10.23
10.2

难点

1.使用c编写的话,需要使用将每一个输入看成字符串,通过strlen对字符串的大小及首字符的判断,判断该项是符号还是数字

2、对运算符通过switch进行 判别,对数字通过小数点进行char到double的转换

3、stack的元素类型是固定的,double

4、输出是保留一位小数%.1f。

5、error的情况对于测试样例只用判断除数是否为0 即可。

通常的情况,应该是使用c++ catch所有的异常。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值