zoukankan      html  css  js  c++  java
  • [Algorithm]一切始于ADT-表达式计算

    Sedgewick的《算法》和Allen Weiss的《算法和数据结构》,这两本比较优秀的算法入门教材第一课都是ADT(abstract data type).无疑,ADT非常有用且非常有趣的知识。刚好最近学校的C语言课程给了一道这样的题目..

    1.问题描述

    从标准输入中读入一个整数算术运算表达式,如5 - 1 * 2 * 3 + 12 / 2 / 2  = 。计算表达式结果,并输出。

    要求:
    1、表达式运算符只有+、-、*、/,表达式末尾的’=’字符表示表达式输入结束,表达式中可能会出现空格;
    2、表达式中不含圆括号,不会出现错误的表达式;
    3、出现除号/时,以整数相除进行运算,结果仍为整数,例如:5/3结果应为1。

    暴力解也不是不可以,但如果使用栈的话,这道题就会变得简单一些..

    2.思路

    利用栈将中缀式转换成后缀表达式,然后再次利用栈对后缀式进行计算

    3.实现

       #include <stdio.h>
       #include <string.h>
       #include <ctype.h>
       #include <stdlib.h>
       int length;
       struct ele
       {
           char op;
           int num;
           int end_flag;
       };
       int postfixtoresult(struct ele *t);
       void infix2postfix(struct ele *t);
       int ele_strlen(struct ele *t);
       void getrank(int *rank,char op);
       struct ele pop(struct ele *stack,struct ele **head);
       void push(struct ele **head,struct ele x);
       int isempty(struct ele *stack,struct ele **head);
       void to_ele_string(char *t,struct ele *ele_t);
       int main()
       {
           char s_buf[100];
           char clean_date[100];
           struct ele ele_buf[100];
           int l,i,k=0;
           for(i=0;i<100;i++)
               ele_buf[i].op=ele_buf[i].end_flag=ele_buf[i].num=0;
           fgets(s_buf,100,stdin);
           l=strlen(s_buf);
           for(i=0;i<l;i++)if(s_buf[i]==' '||s_buf[i]=='='||s_buf[i]=='
    ')continue;else clean_date[k++]=s_buf[i]; clean_date[k]='';
           to_ele_string(clean_date,ele_buf);
           infix2postfix(ele_buf);
           l=postfixtoresult(ele_buf);
           printf("%d",l);
           return 0;
                   
       } 
       void to_ele_string(char *t,struct ele *ele_t)
       {
           char TEMP[10];
           int k=0,m=0,i=0;
           int l=strlen(t);
           for(i=0;i<l;i++)
           {
               if(isdigit(t[i]))
                   TEMP[k++]=t[i];
               else
               {
                   TEMP[k]='';
                   ele_t[m].op = 0;
                   ele_t[m].num = atoi(TEMP);
                   ele_t[m].end_flag = 0;
                   m++;
                   ele_t[m].op = t[i];
                   ele_t[m].num = 0;
                   ele_t[m].end_flag = 0;
                   m++;
                   k=0;
                   memset(TEMP,0,sizeof(TEMP));
               }
           }
           TEMP[k]='';
           ele_t[m].op = 0;
           ele_t[m].num = atoi(TEMP);
           ele_t[m].end_flag = 1;
       }
       int postfixtoresult(struct ele *t)
       {
           struct ele stack[100];
           struct ele *head=stack;
           struct ele TEMP;
           int l=ele_strlen(t);
           int i;
           for(i=0;i<l;i++)
           {
               if(t[i].op==0)
                   push(&head,t[i]);
               else
               {
                   int a,b,r=0;
                   a=pop(stack,&head).num;
                   b=pop(stack,&head).num;
                   switch(t[i].op)
                   {
                       case '+':r=a+b;break;
                       case '-':r=b-a;break;
                       case '*':r=a*b;break;
                       case '/':r=b/a;break;
                   }
                   TEMP.op=0;
                   TEMP.num=r;
                   TEMP.end_flag=0;
                   push(&head,TEMP);
               }
           }
           return pop(stack,&head).num;
       }
       void infix2postfix(struct ele *t)
       {
           struct ele stack[100];
           struct ele *head=stack;
           struct ele out_buf[100];int k=0;
           int i;
           for(i=0;i<100;i++)
           {
               out_buf[i].op=0;
               out_buf[i].end_flag=0;
               out_buf[i].num=0;
           }
           int length=ele_strlen(t);
           int head_rank=0,p_rank=0;
           for(i=0;i<length;i++)
           {
               if(t[i].op==0)
                   out_buf[k++].num=t[i].num;
               else
               {
                   if(isempty(stack,&head))
                   {
                       push(&head,t[i]);
                   }
                   else
                   {
                       getrank(&p_rank,t[i].op);
                       getrank(&head_rank,(*(head-1)).op);
                       while(head_rank>=p_rank)
                       {
                           out_buf[k++]=pop(stack,&head);
                           if(isempty(stack,&head))break;
                           getrank(&head_rank,(*(head-1)).op);
                       }
                       push(&head,t[i]);
                   }
               }
           }
           while(!isempty(stack,&head))
               out_buf[k++]=pop(stack,&head);
           out_buf[k-1].end_flag=1;
           memcpy(t,out_buf,100*sizeof(struct ele));
       }
       int ele_strlen(struct ele *t)
       {
           int i=1;
           while(!t++->end_flag)i++;
           return i;
       }
       void getrank(int *rank,char op)
       {
           switch(op)
           {
               case '*':*rank=2;break;
               case '/':*rank=2;break;
               case '+':*rank=1;break;
               case '-':*rank=1;break;
           }
       }
       int isempty(struct ele *stack,struct ele **head)
       {
           if(*head==stack)
               return 1;
           else return 0;
           return 1;
       }
       void push(struct ele **head,struct ele x)
       {
           **head=x;
           *head=*head+1;
       }
       struct ele pop(struct ele *stack,struct ele **head)
       {
           struct ele null;
           null.end_flag=1;
       
           if(isempty(stack,head))
               return null;
           else
           {
               *head=*head-1;
               return **head;
           }
           return null;
        }
  • 相关阅读:
    杭电 1176 免费馅饼
    IE 8 浏览器 F12 调试功能无法使用
    SqlServer 经常使用分页方法总结
    cocos2d-x 2.0下怎样让BOX2D DEBUG DRAW的方法笔记
    在DIV中自己主动换行
    linux之SQL语句简明教程---主键,外来键
    java数据库连接池技术简单使用
    Windows和linux双系统——改动默认启动顺序
    程序员实用的 MySQL sql 语句
    android 多项对话框
  • 原文地址:https://www.cnblogs.com/cn-lhc/p/6080387.html
Copyright © 2011-2022 走看看