使用栈的表达式计算程序.arith_expr.c
2006-11-14 11:38
309 查看
#include<stdio.h>
#include "arith_expr.h"
#include<assert.h>
#include<ctype.h>
#include<stdlib.h>
#ifndef True
#define True 1
#define False 0
#endif
#define NS_LEN 100
#define OS_LEN 100
struct ns
{
struct NUM nums[NS_LEN];
int top;
};
struct os
{
char ops[OS_LEN];
int top ;
};
struct os opstack;
struct ns numstack;
FILE * listing;
char * str ;
int pos;
void setNum(struct NUM * pn1,struct NUM * pn2)
{
pn1->type = pn2->type;
if (pn1->type == 0)
pn1->value.ivalue = pn2->value.ivalue;
else if (pn1->type == 1)
pn1->value.fvalue = pn2->value.fvalue;
};
int nspush(struct NUM *num)
{
int rel = False;
(numstack.top)++;
if (numstack.top == NS_LEN)
fprintf(listing,"push error:the number stack is full/n");
else
{
(numstack.nums[numstack.top]).type = num->type;
(numstack.nums[numstack.top]).value = num->value; //
rel =True;
}
return(rel);
};
int nspop(struct NUM *num)
{
int rel = False;
if (numstack.top <0)
fprintf(listing,"error:the number stack is empty to pop/n");
else
{
num->type = numstack.nums[numstack.top].type;
num->value = numstack.nums[numstack.top].value;
rel = True;
}
return(rel);
};
char getNextChar()
{
return(str[pos++]);
};
void ungetNextChar()
{ pos--;
};
void getNum(char c)
{
char strvalue[50];
int i,pointnum=0;
struct NUM num;
i = 0;
while (isdigit(c)&&i<=49)
{
strvalue[i++] = c;
c = getNextChar();
}
if (c=='.'&&pointnum==0)
{
pointnum++;
strvalue[i++] = c;
c = getNextChar();
if (!isdigit(c))
{
fprintf(listing,"error.this num has a point .it may be a float,but after the point there is no digit/n ");
return;
}
while(isdigit(c))
{
strvalue[i++] = c;
c = getNextChar();
}
}
else if (c=='.'&&pointnum==1)
{
fprintf(listing,"error:tow points/n");
return;
}
ungetNextChar();
strvalue[i] = '/0';
if (pointnum==0)
{
num.type = 0; // integer
num.value.ivalue = strtol(strvalue,(char **)NULL,10);
}
else
{
num.type = 1; // float
num.value.fvalue = strtof(strvalue,(char**)NULL);
}
nspush(&num);
};
int ospush(char op)
{
opstack.top++;
if (opstack.top == OS_LEN)
{
fprintf(listing,"sorry,the operation statc is full,can not push/n");
return(False);
}
opstack.ops[opstack.top] = op;
return(1);
};
int ospop(char *op)
{
if (opstack.top<0)
{
fprintf(listing,"The operation stack is empty.can not pop/n");
return(False);
}
*op = opstack.ops[opstack.top--];
return(1);
};
void displayns() // to debug
{
int i = 0 ;
while (i <=numstack.top)
{
if (numstack.nums[i].type == 1)
fprintf(listing,"%4.2f/n",numstack.nums[i].value.fvalue);
else
fprintf(listing,"%4d/n",numstack.nums[i].value.ivalue);
i++;
}
};
void displayos() // to debug
{
int i=0;
while(i<=opstack.top)
{
printf("%c top = %-3d/n",opstack.ops[i],opstack.top);
i++;
}
};
int getPriority(char c)
{
if (c =='+'||c=='-')
return(0);
else if (c=='*'||c=='/')
return(1);
else if (c=='('||c==')')
return(2);
else
return(-1);
};
int IsHigh(char src,char des)
{
int s_prio,d_prio;
s_prio = getPriority(src);
d_prio = getPriority(des);
if (s_prio < d_prio)
return(-1);
else if (s_prio == d_prio)
return(0);
else
return(1);
};
void operate_int(int x1,int x2,char c)
{
switch (c)
{
case '+':
numstack.nums[numstack.top].value.ivalue = x1+x2;
return;
case '-':
numstack.nums[numstack.top].value.ivalue = x1-x2;
return;
case '*':
numstack.nums[numstack.top].value.ivalue = x1*x2;
return;
case '/':
numstack.nums[numstack.top].value.ivalue = x1/x2;
return;
}
};
void operate_float(float y1,float y2,char c)
{
switch(c)
{
case '+':
numstack.nums[numstack.top].value.fvalue = y1+y2;
return;
case '-':
numstack.nums[numstack.top].value.fvalue = y1-y2;
return;
case '*':
numstack.nums[numstack.top].value.fvalue = y1*y2;
return;
case '/':
numstack.nums[numstack.top].value.fvalue = y1/y2 ;
return;
}
};
void operate() // pop tow from number stack
{
int x1,x2;
float y1,y2;
char c;
ospop(&c);
if (numstack.nums[numstack.top].type==0 && numstack.nums[numstack.top-1].type==0) //integers
{
x2 = numstack.nums[numstack.top--].value.ivalue;
x1 = numstack.nums[numstack.top].value.ivalue;
operate_int(x1,x2,c);
}
else
{
if (numstack.nums[numstack.top].type==0)
y2 = (float)(numstack.nums[numstack.top--].value.ivalue);
else
y2 =numstack.nums[numstack.top--].value.fvalue;
if (numstack.nums[numstack.top].type==0)
y1 = (float)(numstack.nums[numstack.top].value.ivalue);
else
y1 = numstack.nums[numstack.top].value.fvalue;
numstack.nums[numstack.top].type = 1;
operate_float(y1,y2,c);
}//is
};
void getOp(char c)
{
int temp;
char ch;
if (c=='/0')
{
while (opstack.top>-1)
operate();
return;
}
if (c=='(')
ospush(c);
else if (c==')')
{
operate();
ospop(&c);// pop the '('
if (opstack.top<0) // empty stack
return;
}
else
{
if (opstack.top<0) // empty stack
{
ospush(c);
return;
}
temp = getPriority(opstack.ops[opstack.top]);
if (temp == 2)
{
ospush(c);
return;
}
temp = IsHigh(opstack.ops[opstack.top],c);
while(temp>=0)
{
operate(); // has poped one item
if (opstack.top<0) // empty stack
{
ospush(c);
return;
}
temp = IsHigh(opstack.ops[opstack.top],c);
}
if (temp<0)
ospush(c);
}
};
void init(FILE * fp,char * expr_str)
{
listing = fp;
str = expr_str;
pos = 0;
numstack.top = -1;
opstack.top = -1;
};
struct NUM * compute()
{
char c;
struct NUM * result = NULL;
c= getNextChar();
if (!(isdigit(c)|| c=='('||c==')'))
{
printf("error:the first character is not a digit/n");
return(result);
}
while (c!='/0')
{
if (isdigit(c))
getNum(c);
else if (c=='+'||c=='-'||c=='*'||c=='('||c==')')
getOp(c);
c = getNextChar();
}
getOp(c);
result = (struct NUM * )malloc(sizeof(struct NUM ));
assert(result != NULL);
setNum(result,numstack.nums+numstack.top);
return(result);
};
#include "arith_expr.h"
#include<assert.h>
#include<ctype.h>
#include<stdlib.h>
#ifndef True
#define True 1
#define False 0
#endif
#define NS_LEN 100
#define OS_LEN 100
struct ns
{
struct NUM nums[NS_LEN];
int top;
};
struct os
{
char ops[OS_LEN];
int top ;
};
struct os opstack;
struct ns numstack;
FILE * listing;
char * str ;
int pos;
void setNum(struct NUM * pn1,struct NUM * pn2)
{
pn1->type = pn2->type;
if (pn1->type == 0)
pn1->value.ivalue = pn2->value.ivalue;
else if (pn1->type == 1)
pn1->value.fvalue = pn2->value.fvalue;
};
int nspush(struct NUM *num)
{
int rel = False;
(numstack.top)++;
if (numstack.top == NS_LEN)
fprintf(listing,"push error:the number stack is full/n");
else
{
(numstack.nums[numstack.top]).type = num->type;
(numstack.nums[numstack.top]).value = num->value; //
rel =True;
}
return(rel);
};
int nspop(struct NUM *num)
{
int rel = False;
if (numstack.top <0)
fprintf(listing,"error:the number stack is empty to pop/n");
else
{
num->type = numstack.nums[numstack.top].type;
num->value = numstack.nums[numstack.top].value;
rel = True;
}
return(rel);
};
char getNextChar()
{
return(str[pos++]);
};
void ungetNextChar()
{ pos--;
};
void getNum(char c)
{
char strvalue[50];
int i,pointnum=0;
struct NUM num;
i = 0;
while (isdigit(c)&&i<=49)
{
strvalue[i++] = c;
c = getNextChar();
}
if (c=='.'&&pointnum==0)
{
pointnum++;
strvalue[i++] = c;
c = getNextChar();
if (!isdigit(c))
{
fprintf(listing,"error.this num has a point .it may be a float,but after the point there is no digit/n ");
return;
}
while(isdigit(c))
{
strvalue[i++] = c;
c = getNextChar();
}
}
else if (c=='.'&&pointnum==1)
{
fprintf(listing,"error:tow points/n");
return;
}
ungetNextChar();
strvalue[i] = '/0';
if (pointnum==0)
{
num.type = 0; // integer
num.value.ivalue = strtol(strvalue,(char **)NULL,10);
}
else
{
num.type = 1; // float
num.value.fvalue = strtof(strvalue,(char**)NULL);
}
nspush(&num);
};
int ospush(char op)
{
opstack.top++;
if (opstack.top == OS_LEN)
{
fprintf(listing,"sorry,the operation statc is full,can not push/n");
return(False);
}
opstack.ops[opstack.top] = op;
return(1);
};
int ospop(char *op)
{
if (opstack.top<0)
{
fprintf(listing,"The operation stack is empty.can not pop/n");
return(False);
}
*op = opstack.ops[opstack.top--];
return(1);
};
void displayns() // to debug
{
int i = 0 ;
while (i <=numstack.top)
{
if (numstack.nums[i].type == 1)
fprintf(listing,"%4.2f/n",numstack.nums[i].value.fvalue);
else
fprintf(listing,"%4d/n",numstack.nums[i].value.ivalue);
i++;
}
};
void displayos() // to debug
{
int i=0;
while(i<=opstack.top)
{
printf("%c top = %-3d/n",opstack.ops[i],opstack.top);
i++;
}
};
int getPriority(char c)
{
if (c =='+'||c=='-')
return(0);
else if (c=='*'||c=='/')
return(1);
else if (c=='('||c==')')
return(2);
else
return(-1);
};
int IsHigh(char src,char des)
{
int s_prio,d_prio;
s_prio = getPriority(src);
d_prio = getPriority(des);
if (s_prio < d_prio)
return(-1);
else if (s_prio == d_prio)
return(0);
else
return(1);
};
void operate_int(int x1,int x2,char c)
{
switch (c)
{
case '+':
numstack.nums[numstack.top].value.ivalue = x1+x2;
return;
case '-':
numstack.nums[numstack.top].value.ivalue = x1-x2;
return;
case '*':
numstack.nums[numstack.top].value.ivalue = x1*x2;
return;
case '/':
numstack.nums[numstack.top].value.ivalue = x1/x2;
return;
}
};
void operate_float(float y1,float y2,char c)
{
switch(c)
{
case '+':
numstack.nums[numstack.top].value.fvalue = y1+y2;
return;
case '-':
numstack.nums[numstack.top].value.fvalue = y1-y2;
return;
case '*':
numstack.nums[numstack.top].value.fvalue = y1*y2;
return;
case '/':
numstack.nums[numstack.top].value.fvalue = y1/y2 ;
return;
}
};
void operate() // pop tow from number stack
{
int x1,x2;
float y1,y2;
char c;
ospop(&c);
if (numstack.nums[numstack.top].type==0 && numstack.nums[numstack.top-1].type==0) //integers
{
x2 = numstack.nums[numstack.top--].value.ivalue;
x1 = numstack.nums[numstack.top].value.ivalue;
operate_int(x1,x2,c);
}
else
{
if (numstack.nums[numstack.top].type==0)
y2 = (float)(numstack.nums[numstack.top--].value.ivalue);
else
y2 =numstack.nums[numstack.top--].value.fvalue;
if (numstack.nums[numstack.top].type==0)
y1 = (float)(numstack.nums[numstack.top].value.ivalue);
else
y1 = numstack.nums[numstack.top].value.fvalue;
numstack.nums[numstack.top].type = 1;
operate_float(y1,y2,c);
}//is
};
void getOp(char c)
{
int temp;
char ch;
if (c=='/0')
{
while (opstack.top>-1)
operate();
return;
}
if (c=='(')
ospush(c);
else if (c==')')
{
operate();
ospop(&c);// pop the '('
if (opstack.top<0) // empty stack
return;
}
else
{
if (opstack.top<0) // empty stack
{
ospush(c);
return;
}
temp = getPriority(opstack.ops[opstack.top]);
if (temp == 2)
{
ospush(c);
return;
}
temp = IsHigh(opstack.ops[opstack.top],c);
while(temp>=0)
{
operate(); // has poped one item
if (opstack.top<0) // empty stack
{
ospush(c);
return;
}
temp = IsHigh(opstack.ops[opstack.top],c);
}
if (temp<0)
ospush(c);
}
};
void init(FILE * fp,char * expr_str)
{
listing = fp;
str = expr_str;
pos = 0;
numstack.top = -1;
opstack.top = -1;
};
struct NUM * compute()
{
char c;
struct NUM * result = NULL;
c= getNextChar();
if (!(isdigit(c)|| c=='('||c==')'))
{
printf("error:the first character is not a digit/n");
return(result);
}
while (c!='/0')
{
if (isdigit(c))
getNum(c);
else if (c=='+'||c=='-'||c=='*'||c=='('||c==')')
getOp(c);
c = getNextChar();
}
getOp(c);
result = (struct NUM * )malloc(sizeof(struct NUM ));
assert(result != NULL);
setNum(result,numstack.nums+numstack.top);
return(result);
};
相关文章推荐
- 使用栈的表达式计算程序_arith_expr.h__
- 使用栈的表达式计算程序_Makefile
- 使用栈的表达式计算程序_main.c
- 自己写的程序expr,以计算从命令行输入的逆波尔表达式的值,其中每个运算符或操作数用一个单独的参数表示
- MFC中双缓存机制的使用和实现,程序运行时间计算
- Justinmind使用教程(2)——计算表达式及条件用法
- 网格部件添加表达式计算列使用介绍
- .NET平台开源项目速览(8)Expression Evaluator表达式计算组件使用
- Code Fragment-使用有意义的数字计算表达式代替具体的常量结果
- 我的第一个Qt程序:使用Qt creator和Qt designer完成"HelloWorld"和计算圆面积的程序设计
- 第七章习题 计算1+2+3+...+1000的汇编mbr程序 adc指令使用
- 实验5-2 编制程序,输入m、n(m≥n≥0)后,计算下列表达式的值并输出。 要求将计算阶乘的运算编写作函数fact(n),函数返回值的类型为float。
- 【生物信息学】使用mRNA作为ref时,由bam格式计算rpkm 的 cpp程序
- 使用Spring自带的CronSequenceGenerator来计算cron表达式下次执行日期
- * java程序性能优化 Posted on 2010-07-28 16:04 chinaifne 阅读(2246) 评论(0) 编辑 收藏 一、避免在循环条件中使用复杂表达式
- 使用正则表达式计算PDF文档的页数
- C++第12周报告(一)用循环控制语句编写程序,完成表达式的计算
- 实验5-2: 编制程序,输入m、n(m≥n≥0)后,计算下列表达式的值并输出。 要求将计算阶乘的运算编写作函数fact(n),函数返回值的类型为float
- 使用QueryPerformanceFrequency 计算程序执行时间
- 输入一串字符串形如(2*(1+3)+8)/4 如何使用程序计算出结果 字符串输入计算器