回 帖 发 新 帖 刷新版面

主题:(原创)栈的应用(算术表达式求值)

谁有数据结构题集的实习部分答案 给我份做参考啊共享下 有的联系我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 楼

像[(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 楼

把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 楼


不错 相互学习 不过还是用[8][8]的数组好点 这样也一样 哈哈

14 楼

帮顶
校友吗
呵呵

15 楼


16 楼

8楼的,程序中没有方括号的

17 楼

呵呵~(2+3)*5+4/(-2)
lz试试这个式子
对(-2)这种情况得判定要怎么解决呢?

18 楼


我也写了一个,用到了两个栈,一个栈的元素类型是 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 楼

[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 楼


这个 程序有错误阿

我来回复

您尚未登录,请登录后再回复。点此登录或注册