逆波兰计算器改进版
2015-03-09 20:36
169 查看
前面有写过逆波兰计算器,那时候只能进行个位数计算,现在采用分隔符的办法实现多位数即小数的计算,即在每个数字或者运算符或括号之后加上空格,来确定这个数是否输入结束。逆波兰式保存在一个数组里,然后按照逆波兰计算规则就可以了,注意要使用atof转换。下面是代码部分。#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CAPACITY 50
typedef struct stack
{
int top;
char arr[CAPACITY];
}*pStack,stack;
pStack initStack1()
{
pStack st = (pStack)malloc(sizeof(stack));
st->top = 0;
return st;
}
int stackEmpty1(pStack st)
{
return(st->top <= 0);
}
int stackFull1(pStack st)
{
return(st->top >= CAPACITY);
}
int pushStack1(pStack st, char a)
{
if(stackFull1(st))
{
printf("栈满!\n");
return 0;
}
else
{
st->arr[st->top++] = a;
return 1;
}
}
char popStack1(pStack st)
{
char a;
if(stackEmpty1(st))
{
printf("栈空!\n");
return 0;
}
else
{
a = st->arr[--st->top];
return a;
}
}
char getTop1(pStack st)
{
if(!stackEmpty1(st))
return st->arr[st->top-1];
else
printf("Empty stack");
return 0;
}
typedef struct
{
int top;
float data[CAPACITY];
}*dataStack;
dataStack initStack2()
{
dataStack st = (dataStack)malloc(sizeof(dataStack));
st->top = 0;
return st;
}
int stackEmpty2(dataStack st)
{
return(st->top <= 0);
}
int stackFull2(dataStack st)
{
return(st->top >= CAPACITY);
}
int pushStack2(dataStack st, double data)
{
if(stackFull2(st))
{
printf("栈满!\n");
return 0;
}
else
{
st->data[st->top++] = data;
return 1;
}
}
double popStack2(dataStack st)
{
double data;
if(stackEmpty2(st))
{
printf("栈空!\n");
return 0;
}
else
{
data = st->data[--st->top];
return data;
}
}
double getTop2(dataStack st)
{
if(!stackEmpty2(st))
return st->data[st->top-1];
else
printf("Empty stack");
return 0;
}
int priority(char op)
{
switch(op)
{
case '*':
case '/':return 2;
case '+':
case '-':return 1;
default: return 0;
}
}
int main(void)
{
int p = 0;
int i = 0;
int m;
double result, tmp1, tmp2;
char ch, temp;
char infix[CAPACITY] = "\0";
char output[CAPACITY];
pStack st = initStack1();
dataStack st2 = initStack2();
printf("请输入中缀表达式:");
scanf("%s", &infix);
for(ch = infix[p];ch !='\0';ch = infix[++p])
{
switch(ch)
{
case '(':pushStack1(st,ch);break;
case ')':
{
while(getTop1(st) != '(')
{
output[i++] = ' ';
output[i++] = getTop1(st);
popStack1(st);
}
popStack1(st);
break;
}
case '+':
case '-':
case '*':
case '/':
{
output[i++] = ' ';
while(!stackEmpty1(st))
{
c420
temp = getTop1(st);
if(priority(temp) >= priority(ch))
{
output[i++] = temp;
output[i++] = ' ';
popStack1(st);
}
else
{
break;
}
}
pushStack1(st, ch);
break;
}
default:output[i++] = ch;
}
}
while(!stackEmpty1(st))
{
output[i++] = ' ';
temp = popStack1(st);
output[i++] = temp;
if(temp == '(')
{
printf("表达式有误!");
exit(EXIT_FAILURE);
}
}
output[i] = '\0';
free(st);
printf(" 后缀表达式为:");
for(m = 0; m <= i; m++)
printf("%c", output[m]);
printf("\n");
double num = 0;
char *pt = output;
while(*pt != '\0')
{
while(*pt >= '0' && *pt <= '9')
{
num = 10*num + (*pt - '0');
pt++;
}
if(*pt == '.')
{
pt++;
}
float pow = 1.0;
while(*pt >= '0' && *pt <= '9')
{
pow /= 10;
num = num + (*pt - '0')*pow;
pt++;
}
if(*pt == ' ')
{
if(*(pt-1) >= '0' && *(pt-1) <= '9')
{
pushStack2(st2, num);
num = 0;
}
pt++;
}
if(priority(*pt) > 0)
{
switch(*pt++)
{
case'+':tmp1 = popStack2(st2);tmp2 = popStack2(st2);result = tmp1 + tmp2;pushStack2(st2, result);break;
case'-':tmp1 = popStack2(st2);tmp2 = popStack2(st2);result = tmp2 - tmp1;pushStack2(st2, result);break;
case'*':tmp1 = popStack2(st2);tmp2 = popStack2(st2);result = tmp2 * tmp1;pushStack2(st2, result);break;
case'/':tmp1 = popStack2(st2);tmp2 = popStack2(st2);result = tmp2 / tmp1;pushStack2(st2, result);break;
default:break;
}
}
}
printf(" 计算结果为: %f\n", getTop2(st2));
return 0;
}这个问题从当初的几乎判定为不能进行多位数的运算,到能表达出有多位数的逆波兰表达式,到能实现多位数的计算,一点一点逼近目标。有时候困难并不是想象的那样不可逾越,把复杂的问题细分成很多小步,逐个击破,这是我编写这个程序得到的收获,也是适用于其他学习的学习方法。
#include<stdlib.h>
#include<string.h>
#define CAPACITY 50
typedef struct stack
{
int top;
char arr[CAPACITY];
}*pStack,stack;
pStack initStack1()
{
pStack st = (pStack)malloc(sizeof(stack));
st->top = 0;
return st;
}
int stackEmpty1(pStack st)
{
return(st->top <= 0);
}
int stackFull1(pStack st)
{
return(st->top >= CAPACITY);
}
int pushStack1(pStack st, char a)
{
if(stackFull1(st))
{
printf("栈满!\n");
return 0;
}
else
{
st->arr[st->top++] = a;
return 1;
}
}
char popStack1(pStack st)
{
char a;
if(stackEmpty1(st))
{
printf("栈空!\n");
return 0;
}
else
{
a = st->arr[--st->top];
return a;
}
}
char getTop1(pStack st)
{
if(!stackEmpty1(st))
return st->arr[st->top-1];
else
printf("Empty stack");
return 0;
}
typedef struct
{
int top;
float data[CAPACITY];
}*dataStack;
dataStack initStack2()
{
dataStack st = (dataStack)malloc(sizeof(dataStack));
st->top = 0;
return st;
}
int stackEmpty2(dataStack st)
{
return(st->top <= 0);
}
int stackFull2(dataStack st)
{
return(st->top >= CAPACITY);
}
int pushStack2(dataStack st, double data)
{
if(stackFull2(st))
{
printf("栈满!\n");
return 0;
}
else
{
st->data[st->top++] = data;
return 1;
}
}
double popStack2(dataStack st)
{
double data;
if(stackEmpty2(st))
{
printf("栈空!\n");
return 0;
}
else
{
data = st->data[--st->top];
return data;
}
}
double getTop2(dataStack st)
{
if(!stackEmpty2(st))
return st->data[st->top-1];
else
printf("Empty stack");
return 0;
}
int priority(char op)
{
switch(op)
{
case '*':
case '/':return 2;
case '+':
case '-':return 1;
default: return 0;
}
}
int main(void)
{
int p = 0;
int i = 0;
int m;
double result, tmp1, tmp2;
char ch, temp;
char infix[CAPACITY] = "\0";
char output[CAPACITY];
pStack st = initStack1();
dataStack st2 = initStack2();
printf("请输入中缀表达式:");
scanf("%s", &infix);
for(ch = infix[p];ch !='\0';ch = infix[++p])
{
switch(ch)
{
case '(':pushStack1(st,ch);break;
case ')':
{
while(getTop1(st) != '(')
{
output[i++] = ' ';
output[i++] = getTop1(st);
popStack1(st);
}
popStack1(st);
break;
}
case '+':
case '-':
case '*':
case '/':
{
output[i++] = ' ';
while(!stackEmpty1(st))
{
c420
temp = getTop1(st);
if(priority(temp) >= priority(ch))
{
output[i++] = temp;
output[i++] = ' ';
popStack1(st);
}
else
{
break;
}
}
pushStack1(st, ch);
break;
}
default:output[i++] = ch;
}
}
while(!stackEmpty1(st))
{
output[i++] = ' ';
temp = popStack1(st);
output[i++] = temp;
if(temp == '(')
{
printf("表达式有误!");
exit(EXIT_FAILURE);
}
}
output[i] = '\0';
free(st);
printf(" 后缀表达式为:");
for(m = 0; m <= i; m++)
printf("%c", output[m]);
printf("\n");
double num = 0;
char *pt = output;
while(*pt != '\0')
{
while(*pt >= '0' && *pt <= '9')
{
num = 10*num + (*pt - '0');
pt++;
}
if(*pt == '.')
{
pt++;
}
float pow = 1.0;
while(*pt >= '0' && *pt <= '9')
{
pow /= 10;
num = num + (*pt - '0')*pow;
pt++;
}
if(*pt == ' ')
{
if(*(pt-1) >= '0' && *(pt-1) <= '9')
{
pushStack2(st2, num);
num = 0;
}
pt++;
}
if(priority(*pt) > 0)
{
switch(*pt++)
{
case'+':tmp1 = popStack2(st2);tmp2 = popStack2(st2);result = tmp1 + tmp2;pushStack2(st2, result);break;
case'-':tmp1 = popStack2(st2);tmp2 = popStack2(st2);result = tmp2 - tmp1;pushStack2(st2, result);break;
case'*':tmp1 = popStack2(st2);tmp2 = popStack2(st2);result = tmp2 * tmp1;pushStack2(st2, result);break;
case'/':tmp1 = popStack2(st2);tmp2 = popStack2(st2);result = tmp2 / tmp1;pushStack2(st2, result);break;
default:break;
}
}
}
printf(" 计算结果为: %f\n", getTop2(st2));
return 0;
}这个问题从当初的几乎判定为不能进行多位数的运算,到能表达出有多位数的逆波兰表达式,到能实现多位数的计算,一点一点逼近目标。有时候困难并不是想象的那样不可逾越,把复杂的问题细分成很多小步,逐个击破,这是我编写这个程序得到的收获,也是适用于其他学习的学习方法。
相关文章推荐
- 分享一个Swift语言的逆波兰表达式计算器的实现
- 逆波兰计算器加强版:多项式
- 我的计算器——6 用依赖注入改进
- 栈的应用之简易逆波兰计算器
- 逆波兰计算器与中缀表达式向后缀表达式的转化实例
- 利用栈实现计算器,先转换为逆波兰式之后运算
- 波兰式计算器
- 一个C的逆波兰式计算器的问题
- 逆波兰 计算器 C语言实现
- 基于逆波兰表达式的计算器
- LeetCode OJ:Evaluate Reverse Polish Notation(逆波兰表示法的计算器)
- C程序设计语言逆波兰式计算器学习心得
- 波兰式计算器程序(C++)
- 逆波兰计算器
- 逆波兰计算器:
- 逆波兰计算器(C语言)
- C语言简单计算器(基于栈和逆波兰表达式)这几天忙着开学的事宜,一直没时间刷提,就把今天刚做好的课程设计——简易计算器贴在这给大家参考!(计算小数时要用0减正数并用括号括起来,这一点不足以后再改进)
- java 逆波兰表达式 (后缀表达式) 计算器
- 波兰式计算器程序(C++)
- 逆波兰计算器