栈的应用之表达式求值code_legend
来源:互联网 发布:美人鱼影评知乎 编辑:程序博客网 时间:2024/05/03 04:45
/*
表达式求值
*/
#include "stdio.h"
#include "math.h"
#include "stdlib.h"
#include "process.h"
#define STACKINITSIZE 100
#define STACKINCREMENT 10
typedef struct{
double *base;
double *top;
int stacksize;
}sshu;
typedef struct{
char *base;
char *top;
int stacksize;
}sfu;
char fuhao[8]={'+','-','*','/','(',')','^','#'};
//1初始化栈
//存放数字的栈
void initstackshu(sshu &s)
{
s.base=(double *)malloc(STACKINITSIZE*sizeof(double));
if(!s.base)
exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACKINITSIZE;
}
//存放运算符的栈
void initstackfu(sfu &s)
{
s.base=(char *)malloc(STACKINITSIZE*sizeof(char));
if(!s.base)
exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACKINITSIZE;
}
//2将数字和字符压栈
//压字符
void pushfu(sfu &s,char e)
{
if(s.top-s.base>=s.stacksize)
{
s.base=(char *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(char));
if(!s.base)
exit(OVERFLOW);
s.top=s.base+STACKINCREMENT;
s.stacksize+=STACKINCREMENT;
}
*s.top=e;
s.top++;
}
//压数字
void pushshu(sshu &s,double e)
{
if(s.top-s.base>=s.stacksize)
{
s.base=(double *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(double));
if(!s.base)
exit(OVERFLOW);
s.top=s.base+STACKINCREMENT;
s.stacksize+=STACKINCREMENT;
}
*s.top=e;
s.top++;
}
//3遍历栈顶元素
//看符号栈顶元素
char gettopfu(sfu &s)
{
if(s.top==s.base)
{
printf("eroor1!");exit(0);
}
return *(s.top-1);
}
//看数字栈顶元素
double gettopshu(sshu &s)
{
if(s.top==s.base)
{
printf("eroor2!");exit(0);
}
return *(s.top-1);
}
//4取栈顶元素
//取符号栈顶元素
char popfu(sfu &s)
{
if(s.top==s.base)
{
printf("eroor3!");exit(0);
}
return *(--s.top);
}
//取数字栈顶元素
double popshu(sshu &s)
{
if(s.top==s.base)
{
printf("error4!");exit(0);
}
return *(--s.top);
}
//5检查当前字符是否属于运算符
//很喜欢.将多个数用一个数组存储起来,再一个一个比较.
int in(char c,char *s)
{
int i;
for(i=0;i<8;i++)
if(c==s[i])
return 1;
return 0;
}
//开始定义的符号集合如开头所示。但如果欲实现复杂的熟悉运算,可以考虑
//将符号中的字符数量扩充 对于三角函数,对数函数等,可以考虑用不同的
//简写字母表示函数。如输入的sin可以简写成s。然后再在程序中确立优先级别即可
//6当前字符与栈顶字符的优先级比较
//共8种字符优先级别如下:
//当前字符与栈顶字符比较:
//(:0 +、-:1 *、/:2 ^:3 ):0
//但若当前字符与栈顶字符相同时栈顶优先级低;'('遇到')'时二者优先级相同。
char compare(char s1,char s2)//s1表示栈顶符号,s2表示当前字符.
{
int a1,a2;
if(s1=='('&&s2==')')
return '=';
if(s2=='(')
return '<';
switch(s1)
{
case '(':a1=0;break;
case '+':
case '-':a1=1;break;
case '*':
case '/':a1=2;break;
case '^':a1=3;break;
case ')':a1=0;break;
case '#':a1=-1;break;
default: printf("error5!");exit(0);
}
switch(s2)
{
case '(':a2=0;break;
case '+':
case '-':a2=1;break;
case '*':
case '/':a2=2;break;
case '^':a2=3;break;
case ')':a2=0;break;
case '#':a2=-1;break;
default: printf("error6!");exit(0);
}
if(a1<a2)
return '<';
else if(a1>a2)
return '>';
else if(a1==a2)
return '-';
}
//7单次计算
double calculate(double a,char t,double b)
{
double temp;
switch (t)
{
case '+':temp=a+b;printf("%10.5f+%10.5f=%10.5f\n",a,b,temp);return temp;
case '-':temp=a-b;printf("%10.5f-%10.5f=%10.5f\n",a,b,temp);return temp;
case '*':temp=a*b;printf("%10.5f*%10.5f=%10.5f\n",a,b,temp);return temp;
case '/':temp=a/b;printf("%10.5f/%10.5f=%10.5f\n",a,b,temp);return temp;
case '^':temp=pow(a,b);printf("%10.5f^%10.5f=%10.5f\n",a,b,temp);return temp;
default: printf("eroor7!");exit(0);
}
}
//8求值
double qiuzhi(char *s)
{
sshu shustack;
sfu fustack;
int i=0;
double a,b;
char t;
initstackshu(shustack);
initstackfu(fustack);
pushfu(fustack,'#');
while(s[i]!='#'||gettopfu(fustack)!='#')
{
double m=0,n=0;
if(!in(s[i],fuhao))
{
for(;!in(s[i],fuhao)&&s[i]!='.';i++)
m=10*m+(double)(s[i]-'0');
if(s[i]=='.')
{
int j=1;i++;
for(;!in(s[i],fuhao);i++,j++)
n+=pow(0.1,j)*(s[i]-'0');
}
pushshu(shustack,m+n);
}
else
switch(compare(gettopfu(fustack),s[i]))
{
case '<':pushfu(fustack,s[i]);i++;break;
case '=':popfu(fustack);i++;break;
case '>': case '-':
t=popfu(fustack);b=popshu(shustack);a=popshu(shustack);pushshu(shustack,calculate(a,t,b));break;
default:printf("eroor8!");exit(0);
}
}
return gettopshu(shustack);
}
//9主函数
int main()
{
char string[100]={0};
int d;
printf("欢迎使用简单表达式求值工具\n");
loop1:
printf("请输入表达式,用字符(、+、-*、/ 、^ 、)且是小写半角字符,以#结束输入:\n");
scanf("%s",string);
printf("%10.5f\n",qiuzhi(string));
loop2:
printf("继续使用吗?是请输入1,否请输入2\n");
scanf("%d",&d);
if(d==1)
goto loop1;
else
if(d==2)
{
printf("感谢使用\n");
exit(0);
}
else
{
printf("输入指令错误。\n");
goto loop2;
}
return 0;
}
表达式求值
*/
#include "stdio.h"
#include "math.h"
#include "stdlib.h"
#include "process.h"
#define STACKINITSIZE 100
#define STACKINCREMENT 10
typedef struct{
double *base;
double *top;
int stacksize;
}sshu;
typedef struct{
char *base;
char *top;
int stacksize;
}sfu;
char fuhao[8]={'+','-','*','/','(',')','^','#'};
//1初始化栈
//存放数字的栈
void initstackshu(sshu &s)
{
s.base=(double *)malloc(STACKINITSIZE*sizeof(double));
if(!s.base)
exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACKINITSIZE;
}
//存放运算符的栈
void initstackfu(sfu &s)
{
s.base=(char *)malloc(STACKINITSIZE*sizeof(char));
if(!s.base)
exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACKINITSIZE;
}
//2将数字和字符压栈
//压字符
void pushfu(sfu &s,char e)
{
if(s.top-s.base>=s.stacksize)
{
s.base=(char *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(char));
if(!s.base)
exit(OVERFLOW);
s.top=s.base+STACKINCREMENT;
s.stacksize+=STACKINCREMENT;
}
*s.top=e;
s.top++;
}
//压数字
void pushshu(sshu &s,double e)
{
if(s.top-s.base>=s.stacksize)
{
s.base=(double *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(double));
if(!s.base)
exit(OVERFLOW);
s.top=s.base+STACKINCREMENT;
s.stacksize+=STACKINCREMENT;
}
*s.top=e;
s.top++;
}
//3遍历栈顶元素
//看符号栈顶元素
char gettopfu(sfu &s)
{
if(s.top==s.base)
{
printf("eroor1!");exit(0);
}
return *(s.top-1);
}
//看数字栈顶元素
double gettopshu(sshu &s)
{
if(s.top==s.base)
{
printf("eroor2!");exit(0);
}
return *(s.top-1);
}
//4取栈顶元素
//取符号栈顶元素
char popfu(sfu &s)
{
if(s.top==s.base)
{
printf("eroor3!");exit(0);
}
return *(--s.top);
}
//取数字栈顶元素
double popshu(sshu &s)
{
if(s.top==s.base)
{
printf("error4!");exit(0);
}
return *(--s.top);
}
//5检查当前字符是否属于运算符
//很喜欢.将多个数用一个数组存储起来,再一个一个比较.
int in(char c,char *s)
{
int i;
for(i=0;i<8;i++)
if(c==s[i])
return 1;
return 0;
}
//开始定义的符号集合如开头所示。但如果欲实现复杂的熟悉运算,可以考虑
//将符号中的字符数量扩充 对于三角函数,对数函数等,可以考虑用不同的
//简写字母表示函数。如输入的sin可以简写成s。然后再在程序中确立优先级别即可
//6当前字符与栈顶字符的优先级比较
//共8种字符优先级别如下:
//当前字符与栈顶字符比较:
//(:0 +、-:1 *、/:2 ^:3 ):0
//但若当前字符与栈顶字符相同时栈顶优先级低;'('遇到')'时二者优先级相同。
char compare(char s1,char s2)//s1表示栈顶符号,s2表示当前字符.
{
int a1,a2;
if(s1=='('&&s2==')')
return '=';
if(s2=='(')
return '<';
switch(s1)
{
case '(':a1=0;break;
case '+':
case '-':a1=1;break;
case '*':
case '/':a1=2;break;
case '^':a1=3;break;
case ')':a1=0;break;
case '#':a1=-1;break;
default: printf("error5!");exit(0);
}
switch(s2)
{
case '(':a2=0;break;
case '+':
case '-':a2=1;break;
case '*':
case '/':a2=2;break;
case '^':a2=3;break;
case ')':a2=0;break;
case '#':a2=-1;break;
default: printf("error6!");exit(0);
}
if(a1<a2)
return '<';
else if(a1>a2)
return '>';
else if(a1==a2)
return '-';
}
//7单次计算
double calculate(double a,char t,double b)
{
double temp;
switch (t)
{
case '+':temp=a+b;printf("%10.5f+%10.5f=%10.5f\n",a,b,temp);return temp;
case '-':temp=a-b;printf("%10.5f-%10.5f=%10.5f\n",a,b,temp);return temp;
case '*':temp=a*b;printf("%10.5f*%10.5f=%10.5f\n",a,b,temp);return temp;
case '/':temp=a/b;printf("%10.5f/%10.5f=%10.5f\n",a,b,temp);return temp;
case '^':temp=pow(a,b);printf("%10.5f^%10.5f=%10.5f\n",a,b,temp);return temp;
default: printf("eroor7!");exit(0);
}
}
//8求值
double qiuzhi(char *s)
{
sshu shustack;
sfu fustack;
int i=0;
double a,b;
char t;
initstackshu(shustack);
initstackfu(fustack);
pushfu(fustack,'#');
while(s[i]!='#'||gettopfu(fustack)!='#')
{
double m=0,n=0;
if(!in(s[i],fuhao))
{
for(;!in(s[i],fuhao)&&s[i]!='.';i++)
m=10*m+(double)(s[i]-'0');
if(s[i]=='.')
{
int j=1;i++;
for(;!in(s[i],fuhao);i++,j++)
n+=pow(0.1,j)*(s[i]-'0');
}
pushshu(shustack,m+n);
}
else
switch(compare(gettopfu(fustack),s[i]))
{
case '<':pushfu(fustack,s[i]);i++;break;
case '=':popfu(fustack);i++;break;
case '>': case '-':
t=popfu(fustack);b=popshu(shustack);a=popshu(shustack);pushshu(shustack,calculate(a,t,b));break;
default:printf("eroor8!");exit(0);
}
}
return gettopshu(shustack);
}
//9主函数
int main()
{
char string[100]={0};
int d;
printf("欢迎使用简单表达式求值工具\n");
loop1:
printf("请输入表达式,用字符(、+、-*、/ 、^ 、)且是小写半角字符,以#结束输入:\n");
scanf("%s",string);
printf("%10.5f\n",qiuzhi(string));
loop2:
printf("继续使用吗?是请输入1,否请输入2\n");
scanf("%d",&d);
if(d==1)
goto loop1;
else
if(d==2)
{
printf("感谢使用\n");
exit(0);
}
else
{
printf("输入指令错误。\n");
goto loop2;
}
return 0;
}
0 0
- 栈的应用之表达式求值code_legend
- 栈的应用之括号匹配code_legend
- 栈的应用之进制转换code_legend
- STL栈的应用之表达式求值
- javascript栈的应用之表达式求值
- 栈的应用之表达式求值
- 栈的应用之算术表达式求值
- 栈的应用之表达式求值
- 栈的应用之中缀表达式求值
- 栈的应用 表达式求值
- 表达式求值【栈的应用】
- 栈的应用表达式求值
- 栈的应用-表达式求值
- 栈的应用 表达式求值
- 栈的应用之后缀表达式的求值
- 回顾数据结构之栈的应用-表达式求值
- javascript栈的应用之表达式求值后篇
- 数据结构之栈的应用——四则表达式求值
- 怎样快速学习一门新技术
- TCP那些事(上)
- sql与mongo查询对比
- struts2和数据库模糊查询
- nutch 1.7 修改需要保存建立索引的数据
- 栈的应用之表达式求值code_legend
- SharedPreferences
- 棋牌游戏避免失败的5个技巧
- Android Bitmap 全面解析(二)加载多张图片的缓存处理 ...
- ICMP:Internet控制报文协议
- 来自苹果的编程语言——Swift简介
- asp.net多线程session 失效
- 栈的应用之进制转换code_legend
- cocos2dx-3.0(6)------Label、LabelTTF、LabelAtlas、LabelBMFont使用之法