zoukankan      html  css  js  c++  java
  • 表达式求值--数据结构C语言算法实现

    这篇博客介绍的表达式求值是用C语言实现的,只使用了c++里面的引用。

    数据结构课本上的一个例题,但是看起来很简单,实现却遇到了很多问题。

    这个题需要构建两个栈,一个用来存储运算符OPTR, 一个用来存储数字OPND。

    但是,数字和运算符都定义成字符型栈吗?

    出现了问题,当运算结果或中间结果为负时,没有办法存储。而且只能运算0~9之间的数字结果也只能是0~9之间。

    那就运算符栈为字符栈, 数字栈为数值型栈,在存储时将表达式中的字符转化成数值进行存储。

    但是,如果我们不用c++里面的stack进行栈的定义,而是用C语言进行实现,这种方法实现起来好像也没有这么简单,代码很多。两种栈的元素类型不一样,操作很繁琐。

    怎么办呢, 我想可以用char类型的ASCII码数值来表示数值,两个栈都定义为字符栈。

    数值进行存储时,将读入的字符型变量值减去0的ASCII码值  c - '0' ,然后压栈。

    但这样做也有缺陷,应为C语言中char类型只有8位, 那这种方法实现的表达式求值,其结果和中间值的取值范围[ -128, 127] 。

     我们主要是学习栈的实现和应用,其实对于这个题来说已经足够了。

    下面附上代码的实现:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 
      5 #define ElemType char
      6 #define STACKINCEMENT 10
      7 #define STACK_INIT_SIZE 50
      8 
      9 #define Status int
     10 #define OK 1
     11 #define ERROR 0
     12 #define OVERFLOW -2
     13 
     14 typedef struct{
     15     ElemType *base;
     16     ElemType *top;
     17     int stacksize;
     18 }SqStack;
     19 
     20 Status InitStack(SqStack &S){
     21     S.top = S.base = (ElemType *)malloc(sizeof(ElemType) * STACK_INIT_SIZE);
     22     if(!S.top)
     23         exit(OVERFLOW);
     24     S.stacksize = STACK_INIT_SIZE;
     25     return OK;
     26 }//InitStack
     27 
     28 Status Push(SqStack &S, ElemType e){
     29     if(S.top - S.base == S.stacksize){
     30         S.base = (ElemType *)realloc(S.base, sizeof(ElemType) *
     31                                    (S.stacksize + STACKINCEMENT));
     32         if(!S.base) exit(OVERFLOW);
     33         S.top = S.base + S.stacksize;
     34         S.stacksize += STACKINCEMENT;
     35     }
     36     *S.top++ = e;
     37     return OK;
     38 }//Push
     39 
     40 Status Pop(SqStack &S, ElemType &e){
     41     if(S.base == S.top) return ERROR;
     42 
     43     e = *--S.top;
     44     return OK;
     45 }//Pop
     46 
     47 ElemType GetTop(SqStack S){
     48     if(S.base == S.top) return ERROR;
     49     return *--S.top;
     50 }//GetTop
     51 
     52 Status In(ElemType c){
     53     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='#'||c=='('||c==')'||c=='['||c==']')
     54         return 1;
     55     else
     56         return 0;
     57 }//In
     58 
     59 char Precede(ElemType a, ElemType b){
     60     if(a=='+'||a=='-'){
     61         if(b=='+'||b=='-'||b=='>'||b=='#'||b==')'||b==']')
     62             return '>';
     63         else return '<';
     64     }
     65     if(a=='*'||a=='/'){
     66         if(b=='('||b=='[')
     67             return '<';
     68         else return '>';
     69     }
     70     if(a=='('){
     71         if(b==')')
     72             return '=';
     73         else return '<';
     74     }
     75     if(a=='['){
     76         if(b==']')
     77             return '=';
     78         else return '<';
     79     }
     80     if(a=='#'){
     81         if(b=='#')
     82             return '=';
     83         else return '<';
     84     }
     85 }//Precede
     86 
     87 ElemType Operate(ElemType a, ElemType x, ElemType b){
     88     switch (x){
     89     case '+':
     90         return a  + b;
     91     case '-':
     92         return a  - b;
     93     case '*':
     94         return a * b;
     95     case '/':
     96         return a / b;
     97     }
     98 }//Operator
     99 
    100 ElemType EvaluateExpression(){
    101     SqStack OPTR, OPND;
    102     InitStack(OPTR); //操作符
    103     Push(OPTR, '#');
    104     InitStack(OPND); //操作数
    105 
    106     char x, c[100];
    107     gets(c);
    108     int i=0;
    109     while(c[i] != '#' || GetTop(OPTR)!='#'){
    110         if(!In(c[i])) {
    111             if(i>0 && (c[i-1]>'0'&& c[i-1]<='9')){
    112                 Pop(OPND, x);
    113                 Push(OPND, 10*x + c[i] - '0');
    114             }
    115             else Push(OPND, c[i] - '0');
    116             i++;
    117         }
    118         else
    119             switch(Precede(GetTop(OPTR), c[i])){
    120             case '<':
    121                 Push(OPTR, c[i]);
    122                 i++;
    123                 break;
    124             case '=':
    125                 Pop(OPTR, x);
    126                 i++;
    127                 break;
    128             case '>':
    129                 Pop(OPTR, x);
    130                 ElemType a, b;
    131                 Pop(OPND, b); Pop(OPND, a);
    132                 Push(OPND, Operate(a, x, b));
    133                 break;
    134             }
    135     }
    136     return GetTop(OPND);
    137 }//EvaluateExpression
    138 
    139 int main(){
    140     SqStack S;
    141     InitStack(S);
    142     printf("%d",EvaluateExpression());
    143 
    144     return 0;
    145 }
  • 相关阅读:
    使用node.js如何爬取网站数据
    关于@font-face的使用
    webpack通过postcss-loader添加浏览器前缀
    点击弹出 +1放大效果 -- jQuery插件
    网站CSS选择器性能讨论
    修改 上传图片按钮input-file样式。。
    insertAdjacentHTML方法示例
    css背景色半透明的最佳实践
    js实现选中文字 分享功能
    js实现滑动的弹性导航
  • 原文地址:https://www.cnblogs.com/Dawn-bin/p/9824734.html
Copyright © 2011-2022 走看看