数据结构学习录(二)——用栈做出一个简单计算器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;
}