主题:(原创)栈的应用(算术表达式求值)
大象踩蚂蚁
[专家分:0] 发布于 2006-04-04 07:56:00
谁有数据结构题集的实习部分答案 给我份做参考啊共享下 有的联系我QQ327489180
自己写了个和大家共享下
认为好用的 给我顶下~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include<stdlib.h>
#include<stdio.h>
#define stack_init_size1 40
#define stack_init_size2 20
#define stackincrement1 40
#define stackincrement2 20
typedef struct{
int *base;
int *top;
int stacksize;
}s_stack;
typedef struct{
char *base;
char *top;
int stacksize;
}f_stack;
static char youxian[7][7]=
{
{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','>'},{'>','>','>','>','>','>','>'},
{'<','<','<','<','<','>','='}
};
int in(char c)
{
switch(c)
{
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
case '#':return 6;
default:return 9;
}
}
void s_push(s_stack *s,int e)
{
if(s->top-s->base>=s->stacksize)
{
s->base=(int *)realloc(s->base,(s->stacksize+stackincrement1)*sizeof(int));
if(!s->base) exit(0);
s->top=s->base+s->stacksize;
s->stacksize+=stackincrement1;
}
*s->top=e; s->top++;
/*printf("the s_stack has the data:%d\n",*(s->top-1));*/
}
void f_push(f_stack *f,char e)
{
if(f->top-f->base>=f->stacksize)
{
f->base=(char *)realloc(f->base,(f->stacksize+stackincrement2)*sizeof(char));
if(!f->base) exit (0);
f->top=f->base+f->stacksize;
f->stacksize+=stackincrement2;
}
*f->top=e;f->top++;
/* printf("the f_stack has the sign:%c\n",*(f->top-1));*/
}
int s_gettop(s_stack *s)
{
s->top--;
return *s->top;
}
char f_gettop(f_stack *f)
{
f->top--;
return *f->top;
}
char pduan(f_stack *f,char c)
{
int m,n;
char w;
m=in(c);
w=*(f->top-1);
n=in(w);
return youxian[n][m];
}
int yunsuan(int p,char r,int q)
{
switch(r)
{
case '+': return q+p;
case '-': return q-p;
case '*': return q*p;
case '/': return q/p;
}
}
回复列表 (共36个回复)
11 楼
jackyin666 [专家分:10] 发布于 2006-04-11 22:31:00
像[(3+4)*5]/5的已经可以了,我稍微作了一点改动
#include<stdlib.h>
#include<stdio.h>
#define stack_init_size1 40
#define stack_init_size2 40
#define stackincrement1 40
#define stackincrement2 40
typedef struct{
int *base;
int *top;
int stacksize;
}opnd_stack;
typedef struct{
char *base;
char *top;
int stacksize;
}optr_stack;
static char youxian[8][7]=
{
{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','>'},{'>','>','>','>','>','>','>'},
{'<','<','<','<','<','>','='},{'<','<','<','<','<','>','<'}
};
int in(char c)
{
switch(c)
{
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
case '[': return 6;
case ']': return 6;
case '#':return 7;
default:return 9;
}
}
void opnd_push(opnd_stack *s,int e)
{
if(s->top - s->base >= s->stacksize) /*栈满,追加存储空间*/
{
s->base=(int *)realloc(s->base,(s->stacksize+stackincrement1)*sizeof(int));
if(!s->base) exit(0);
s->top=s->base+s->stacksize;
s->stacksize+=stackincrement1;
}
*s->top++=e;
}
void optr_push(optr_stack *f,char e)
{
if(f->top - f->base >= f->stacksize) /*栈满,追加存储空间*/
{
f->base=(char *)realloc(f->base,(f->stacksize+stackincrement2)*sizeof(char));
if(!f->base) exit (0);
f->top=f->base+f->stacksize;
f->stacksize+=stackincrement2;
}
*f->top++=e;
}
int opnd_gettop(opnd_stack *s)
{
s->top--;
return *s->top;
}
char optr_gettop(optr_stack *f)
{
f->top--;
return *f->top;
}
char pduan(optr_stack *f,char c)
{
int m,n;
char w;
m=in(c);
w=*(f->top-1);
n=in(w);
return youxian[n][m];
}
int yunsuan(int p,char r,int q)
{
switch(r)
{
case '+': return q+p;
case '-': return q-p;
case '*': return q*p;
case '/': return q/p;
}
}
12 楼
jackyin666 [专家分:10] 发布于 2006-04-11 22:44:00
把static char youxian[7][7]=
{
{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','>'},{'>','>','>','>','>','>','>'},
{'<','<','<','<','<','>','='}
};
改为
static char youxian[8][7]=
{
{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','>'},{'>','>','>','>','>','>','>'},
{'<','<','<','<','<','>','='},{'<','<','<','<','<','>','<'}
};
将int in(char c)
{
switch(c)
{
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
case '#':return 6;
default:return 9;
}
}
改为
static int in(char c)
{
switch(c)
{
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
case '[': return 6;
case ']': return 6;
case '#':return 7;
default:return 9;
}
}
13 楼
大象踩蚂蚁 [专家分:0] 发布于 2006-04-12 13:09:00
不错 相互学习 不过还是用[8][8]的数组好点 这样也一样 哈哈
14 楼
flyskylf [专家分:0] 发布于 2006-04-17 19:59:00
帮顶
校友吗
呵呵
15 楼
不知 [专家分:0] 发布于 2006-04-18 20:45:00
16 楼
Tokyson [专家分:90] 发布于 2006-04-20 16:47:00
8楼的,程序中没有方括号的
17 楼
北溟有渔 [专家分:40] 发布于 2006-05-05 23:11:00
呵呵~(2+3)*5+4/(-2)
lz试试这个式子
对(-2)这种情况得判定要怎么解决呢?
18 楼
419Labs [专家分:50] 发布于 2006-05-07 12:36:00
我也写了一个,用到了两个栈,一个栈的元素类型是 double,另一个栈的元素类型是 char,用 union 把它们结合在一起,这样就可以用同一套pop()和push()函数来处理两个栈了,否则就要写两套大同小异的pop()和push()。
[code]
/* infix calculator version 0.1.3 #20060428
* by 419Labs
* kikistar.com@gmail.com
* http://my.opera.com/419/
*
* References:
* 1.[K&R] The C Programming Language (second edition)
* 影印版 ISBN 7-302-02412-X/TP.1214
* 2.[Mark Allen Weiss] Data Structures and Algorithm Analysis in C
(second edition) 中文版 ISBN 7-111-12748-X
* 3.[严蔚敏 吴伟民] 数据结构(C语言版) ISBN 7-900643-22-2
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXOP 100
#define NUMBER '0' // signal that a number was found
#define EMPTY 0
enum Optype { ND, TOR }; // ND for operand, TOR for operator
union Era
{
double nd; // op.era.nd
char tor; // op.era.tor
};
struct Op
{
int max;
int top;
enum Optype type;
union Era *era;
};
struct Op *create_stack(int max, enum Optype);
void push(union Era, struct Op *);
union Era pop(struct Op *);
void nullerr(void);
int getop(char []);
double operate(struct Op *opnd, struct Op *optor);
void print_stack(struct Op *op);
char top_tor(struct Op *);
int
main()
{
int c;
char s[MAXOP];
union Era era;
struct Op *opnd;
struct Op *optor;
opnd = create_stack(MAXOP, ND);
optor = create_stack(MAXOP, TOR);
printf(" 本程序可进行“加减乘除(+ - * /)”四则混合运算。\n");
printf(" 输入 q 或按 Ctrl+C 退出程序。\n");
printf(" 输入算式后按回车即可算出答案:\n\n");
while ((c = getop(s)) != EOF) {
switch (c) {
case NUMBER:
if (opnd->top > optor->top + 1) { // 如果是逆波兰算式
printf("\tparse error\n");
while (getchar() != '\n')
/*void*/;
opnd->top = EMPTY;
era.nd = 0.0;
}
else
era.nd = atof(s);
push(era, opnd);
break;
case '+': // + 和 - 优先级最低,把除了 '(' 以外的全部操作符弹出后入栈
case '-':
if (optor->top == EMPTY) {
era.tor = c;
push(era, optor);
}
else {
while (optor->top > EMPTY)
if (top_tor(optor) == '(')
break;
else {
era.nd = operate(opnd, optor);
push(era, opnd);
}
era.tor = c;
push(era, optor);
}
break;
case '*': // 乘除优先级最高,把相同优先级的乘和除弹出后入栈
case '/':
if (optor->top == EMPTY) {
era.tor = c;
push(era, optor);
}
else {
while (optor->top > EMPTY)
if (((era.tor = top_tor(optor)) == '+')
|| (era.tor == '-')
|| (era.tor == '('))
break;
else {
era.nd = operate(opnd, optor);
push(era, opnd);
}
era.tor = c;
push(era, optor);
}
break;
case '(': // '(' 不作运算,直接放入optor栈。
era.tor = c;
push(era, optor);
break;
case ')': // 把 '(' 之前的全部操作符弹出,计算后把 '(' 也弹出
while (optor->top > EMPTY)
if (top_tor(optor) == '(')
break;
else {
era.nd = operate(opnd, optor);
push(era, opnd);
}
pop(optor);
break;
case '\n': // 把余下的操作符全部弹出,计算后输出结果
if (opnd->top == EMPTY)
/*do nothing*/;
else
while (optor->top > EMPTY)
if (top_tor(optor) == '(')
pop(optor);
else {
era.nd = operate(opnd, optor);
push(era, opnd);
}
era = pop(opnd);
printf("\t%.8g\n", era.nd);
break;
case 'p':
print_stack(opnd);
getchar();
break;
case 'q':
exit(0);
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
[/code]
19 楼
419Labs [专家分:50] 发布于 2006-05-07 12:39:00
[code]
struct Op *create_stack(int max, enum Optype type)
{
struct Op *op;
op = malloc(sizeof(*op));
if (op == NULL)
nullerr();
op->era = calloc(sizeof(union Era), max);
if (op->era == NULL)
nullerr();
op->max = max;
op->top = EMPTY;
op->type = type;
return op;
}
void
push(union Era era, struct Op *op)
{
if (op->top >= op->max) {
if (op->type == ND)
printf("error: stack full, can't push %g\n", era.nd);
else
printf("error: stack full, can't push %c\n", era.tor);
}
else
op->era[op->top++] = era;
}
union Era
pop(struct Op *op)
{
if (op->top > EMPTY)
return op->era[--op->top];
else {
printf("error: stack empty\n");
if (op->type == ND)
op->era[EMPTY].nd = 0.0;
else
op->era[EMPTY].tor = 0;
return op->era[EMPTY];
}
}
void nullerr(void)
{
printf("not enough memory\n");
exit(1);
}
int getop(char s[]) // [K&R] section 4.3
{
int i, c;
while ((s[0] = c = getchar()) == ' ' || c == '\t')
/*do nothing*/;
s[1] = '\0';
if (!isdigit(c) && c != '.')
return c; // not a number
i = 0;
if (isdigit(c)) // collect integer part
while (isdigit(s[++i] = c = getchar()))
;
if (c == '.') // collect fraction part
while (isdigit(s[++i] = c = getchar()))
/*do nothing*/;
s[i] = '\0';
if (c != EOF)
ungetc(c, stdin);
return NUMBER;
}
double operate(struct Op *opnd, struct Op *optor)
{
union Era nd1, nd2, tor;
nd2 = pop(opnd);
nd1 = pop(opnd);
tor = pop(optor);
switch (tor.tor) {
case '+':
return nd1.nd + nd2.nd;
break;
case '-':
return nd1.nd - nd2.nd;
break;
case '*':
return nd1.nd * nd2.nd;
break;
case '/':
return nd1.nd / nd2.nd;
break;
default:
return 0.0;
break;
}
}
void print_stack(struct Op *op)
{
int i;
for (i = op->top; i > 0; i--)
printf("%g\n", op->era[i].nd);
}
char top_tor(struct Op *op)
{
return op->era[op->top-1].tor; // after push, top plus one
}
[/code]
20 楼
heming55 [专家分:70] 发布于 2006-05-10 11:01:00
这个 程序有错误阿
我来回复