数据结构学习录(二)——用栈做出一个简单计算器2 C程序

数据结构学习录(二)——用栈做出一个简单计算器2 C程序

之前一个整数的,现在把 浮点数 的计算放上。

同样是建立两个栈,一个存放数字 类型是浮点的,一个存放符号 类型是整数,字符型的也可以。

下面的这个程序存放符号的是 整数型 的:

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 1000
typedef float Status;

typedef struct node1   //数字栈  Node1   Stack1
{
	float date1;
	struct node1 *next1;
}Node1;

typedef struct stack1
{
	Node1 *top1;
	Node1 *base1;
	int count1;
}Stack1;

int InitStack1(Stack1 **s)      //数字栈申请空间 
{ 
	if(s == NULL)
	{
		return 0;
	}
 
	(*s) = (Stack1 *)malloc(sizeof(Stack1));
 
	if(*s == NULL)
	{
		return 0;
	}
 
	(*s) -> top1 = NULL;
	(*s) -> base1 = NULL;
	(*s) -> count1 = 0;
 
	return 1;
}

int Push1(Stack1 **s,Status e)  //数字入栈 
{
	if(s == NULL || (*s) == NULL)
	{
		return 0;
	}

	Node1 *p = (Node1 *)malloc(sizeof(Node1));
 
	p -> date1 = e;
	p -> next1 = (*s) -> top1;
	(*s) -> top1 = p;
	(*s) -> count1++;
 
	return 1;

}

Status Pop1(Stack1 **s)           //数字出栈 
{
	float e;
	Node1 *p = (*s) -> top1;
	
	if(s == NULL || (*s) == NULL)
	{
		return 0;
	}
 
    e = (*s) -> top1 -> date1;
    (*s) -> top1 = (*s) -> top1 -> next1;
    (*s) -> count1--;
    free(p);
 
    return e;
}



typedef struct node2  //符号栈   Node2   Stack2 
{
	int date2;
	struct node2 *next2;
}Node2;
 
typedef struct stack2
{
	Node2 *top2;
	Node2 *base2;
	int count2;
}Stack2;

int InitStack2(Stack2 **s)      //符号栈申请空间 
{ 
	if(s == NULL)
	{
		return 0;
	}
 
	(*s) = (Stack2 *)malloc(sizeof(Stack2));
 
	if(*s == NULL)
	{
		return 0;
	}
 
	(*s) -> top2 = NULL;
	(*s) -> base2 = NULL;
	(*s) -> count2 = 0;
 
	return 1;
}

int LinkStackEmpty(Stack2 *s)    //判断符号栈是否为空 
{
	return (s->top2 == NULL)? 1 : 0;
}

Status Push2(Stack2 **s,int e)  //符号入栈 
{
	if(s == NULL || (*s) == NULL)
	{
		return 0;
	}

	Node2 *p = (Node2 *)malloc(sizeof(Node2));
 
	p -> date2 = e;
	p -> next2 = (*s) -> top2;
	(*s) -> top2 = p;
	(*s) -> count2++;
 
	return 1;

}

int GetTop(Stack2 *s)            //获取符号栈顶元素 
{
	if(s == NULL || s->top2 == NULL)
	{
		return 0;
	}
 
	return s->top2->date2;
}

int Pop2(Stack2 **s)             //符号出栈 
{
	float e;
	Node2 *p = (*s) -> top2;
	
	if(s == NULL || (*s) == NULL)
	{
		return 0;
	}
 
    e = (*s) -> top2 -> date2;
    (*s) -> top2 = (*s) -> top2 -> next2;
    (*s) -> count2--;
    free(p);
 
    return e;
}

Status Switch(char e)            //比较级别 
{
	switch(e)
	{	 
	case  '(': return 3.0;
	case  '*': 
	case  '/': return 2.0;
	case  '+': 
	case  '-': return 1.0;
	}
}


int main() 
{
	Stack1  *s_num;    //建立两个栈,s_char用来放计算符号,s_num用来放还原后的数字 
	Stack2  *s_char;                                    
	char input[MAXSIZE] = {0};                                     //用来存放输入的表达式 
	Status num1 = 0.0, num2 = 0.0,temp = 0.0, change = 0.1;
 	int flag = 1,i = 0;                                            //判断小数点 
 	
	if(!InitStack2(&s_char)  || !InitStack1(&s_num))                 //判断栈的空间获取是否成功 
	{
		printf("栈申请失败 \n");
	}
	
 
	printf("请输入表达式: \n");     //输入表达式      
	scanf("%s",input);
	
	while(input[i] != '\0' || !LinkStackEmpty(s_char))
	{
		if((input[i] >= '0' && input[i] <= '9') || input[i] == '.')                  //判断输入的是否为数字 
		 {
		 	
		 	if(flag == 1 && input[i] >= '0' && input[i] <= '9')             //小数点之前的部分 
			{
			 	temp = temp * 10 + input[i] - '0';          
			}
			if(input[i] == '.')                                             //判断小数点 
			{
				flag = 0;
			}
			if(flag == 0 && input[i] >= '0' && input[i] <= '9')             //小数点后面的部分 
			{
				temp = temp + (input[i] - '0') * change;
				change = change / 10.0;     
			}
			
			i++;
			if(input[i] != '.' && (input[i] > '9' || input[i] < '0'))          //当输入的下一个值不是数字时 
			{
				Push1(&s_num, temp);                                   //将计算好的temp放入s_num中 	
				temp = 0; change = 0.1; flag = 1;
			}
		 }
		 else
		 {		 
			if(input[i] == ')' && GetTop(s_char) == '(' ) //如果此时的符号为 (  且符号栈中的最上面的是  ) ,将  )  弹出 
			{
				Pop2(&s_char); 
				i++;
				continue;
			}
			 
			if((input[i] != ')' && (GetTop(s_char) == '(')) || (LinkStackEmpty(s_char)) || (Switch(input[i]) > Switch(GetTop(s_char))) )         //输入符号 
			 {
			 	
		 		Push2(&s_char,input[i]);
		 		i++;
		 		continue;
			 }
			 
			if((Switch(input[i]) <= Switch(GetTop(s_char))) || (input[i] != '(' && input[i] == ')' ) || (!LinkStackEmpty(s_char) && (input[i] == '#')))    //进行计算 
		 	{

		 		switch(Pop2(&s_char))
				{
					case'+': num1 = Pop1(&s_num); num2 = Pop1(&s_num); Push1(&s_num, (num2 + num1)); break;
					case'-': num1 = Pop1(&s_num); num2 = Pop1(&s_num); Push1(&s_num, (num2 - num1)); break;
					case'*': num1 = Pop1(&s_num); num2 = Pop1(&s_num); Push1(&s_num, (num2 * num1)); break;
					case'/': num1 = Pop1(&s_num); num2 = Pop1(&s_num); Push1(&s_num, (num2 / num1)); break;				  				 
				 }	 
			}
		}
	}
	
	printf("%f",Pop1(&s_num));
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值