• 计算用字符串表示的整数四则运算的值


    昨天晚上写完《计算用字符串表示的个位数四则运算的值(栈)》,自己给自己留了个问题?即,怎样计算用字符串表示的整数四则运算的值。这里增加了两个难度,整数的位数不再是一位,而且表达式中可以含括号。下面给出代码:

    View Code
      1 #include <iostream>
      2 using namespace std;
      3 
      4 const int MAX=100;
      5 
      6 typedef struct node * pointer;
      7 typedef struct node{
      8     bool isNumber;
      9     int value;
     10     pointer next;
     11 }Node,*list;
     12 
     13 inline bool isnum(char c)
     14 {
     15     return (c<='9' && c>='0');
     16 }
     17 inline int char2num(char c)
     18 {
     19     return (c-'0');
     20 }
     21 
     22 //验证字符串是否是有效的整数四则运算表达式
     23 bool valid(const char *str){
     24     int i, len=strlen(str);
     25     //逐个验证字符及其前后关系是否为有效
     26     if(!isnum(str[0]) && str[0]!='(' && str[0]!='-')
     27         return false;
     28     for(i=1;i<len;i++)    {
     29         if(isnum(str[i-1]) && str[i]=='(')
     30             return false;
     31         if(str[i-1]=='(' && (str[i]=='+' || str[i]=='*' || str[i]=='/' || str[i]==')'))
     32             return false;        
     33         if(str[i-1]==')' && (isnum(str[i]) || str[i]=='(' || str[i]==')'))
     34             return false;
     35         if((str[i-1]=='+' || str[i-1]=='-' || str[i-1]=='*' || str[i-1]=='/') && str[i]==')')
     36             return false;
     37     }
     38     if(!isnum(str[len-1]) && str[len-1]!=')')
     39         return false;
     40     //验证括号是否配对
     41     char stack[MAX];
     42     int top=-1;
     43     for(i=0;i<len;i++)    {
     44         if(str[i]=='(')
     45             stack[++top]='(';
     46         if(str[i]==')')
     47             if(top==-1)
     48                 return false;
     49             else
     50                 top--;
     51     }
     52     if(top!=-1)
     53         return false;
     54     return true;
     55 }
     56 
     57 //将字符串格式化为链表
     58 list format(const char *str)
     59 {
     60     pointer head=new Node;
     61     pointer rear=head;
     62     int len=strlen(str);
     63     for(int i=0;i<len;){
     64         pointer s=new Node;
     65         if(isnum(str[i])) {
     66             int j=1,sum=0,k;
     67             while(isnum(str[i+j])) j++;
     68             for(k=0;k<j;k++)
     69                 sum=sum*10+char2num(str[i+k]);
     70             s->isNumber=true;
     71             s->value=sum;
     72             i+=j;
     73         }
     74         else{
     75             s->isNumber=false;
     76             s->value=str[i];
     77             i++;
     78         }
     79         rear->next=s;
     80         rear=s;
     81     }
     82     rear->next=NULL;
     83     return head;
     84 }
     85 
     86 //计算first结点和end结点之间表达式的值
     87 //注意子表达式应该不含括号
     88 //这里first_pre指向first的前一个结点
     89 //end_next指向end的后一个结点
     90 //之所以这么定义,是为了调用函数和函数实现的方便
     91 int _eval(pointer first_pre, pointer end_next)
     92 {
     93     pointer first=first_pre->next;
     94     pointer stack[MAX];
     95     int top=-1;
     96     //如果首节点为负号
     97     if(!first->isNumber && first->value=='-')    {
     98         first=first->next;
     99         first->value=-first->value;
    100     }
    101     stack[++top]=first;
    102     pointer p=first->next;
    103     while(p!=end_next) {
    104         if(p->value=='*')
    105             stack[top]->value=stack[top]->value * p->next->value;
    106         else if(p->value=='/')
    107             stack[top]->value=stack[top]->value / p->next->value;
    108         else  {
    109                 stack[++top]=p;
    110                 stack[++top]=p->next;
    111         }
    112         p=p->next->next;
    113     } 
    114     int result=stack[0]->value;
    115     for(int i=1;i<top;i+=2)
    116         if(stack[i]->value=='+')
    117             result+=stack[i+1]->value;
    118         else if(stack[i]->value=='-')
    119             result-=stack[i+1]->value;
    120     return result;
    121 }
    122 
    123 //计算整个表达式的值
    124 int eval(const char *str)
    125 {
    126     if(!valid(str)){
    127         cout<<"Your arithmetic expression is't valid."<<endl;
    128         exit(0);
    129     }
    130     list head=format(str);
    131     pointer stack[MAX]; //栈,用于保存指向左括号结点的指针
    132     int top;
    133     top=-1;
    134     pointer p=head;
    135     //计算所有括号对之间的子表达式的值
    136     while((p=p->next)!=NULL){
    137         if(!p->isNumber && p->value=='(')
    138                 stack[++top]=p;
    139         if(p->value==')'){
    140             pointer left_bracket=stack[top--];//指向左括号结点的指针
    141             //计算一对括号之间表达式(记作一个子表达式)的值
    142             int temp=_eval(left_bracket,p);
    143             //将该子表达式捏做一个结点
    144             left_bracket->isNumber=true;
    145             left_bracket->value=temp;
    146             left_bracket->next=p->next;
    147         }
    148     }
    149     //计算整个表达式的值,注意此时表达式已不含括号
    150     return _eval(head,NULL);
    151 }
    152 
    153 int main()
    154 {
    155     char *str = "-(128*215-918)/((21+47)*53/272-99)/35+(78-0)*0";
    156     int result=-(128*215-918)/((21+47)*53/272-99)/35+(78-0)*0;
    157     cout<<result<<" "<<eval(str)<<endl;
    158 
    159     system("pause");
    160     return 0;
    161 }

    运行结果就不贴了,感兴趣的朋友,可以自己试试。

    不足之处,欢迎交流。

  • 相关阅读:
    JAVA8十大新特性详解
    博客主题
    nideshop小程序商城部署
    Eclipse创建Maven多模块工程Module开发(图文教程)
    将博客搬至CSDN
    腾讯开源软件镜像站上线
    python-应用OpenCV和Python进行SIFT算法的实现
    初学node.js-nodejs中实现删除用户路由
    本博客正在实验姿态捕捉,可以尝试允许摄像头运行
    博客园如何实现看板娘Live2d?来吧少年,开启新世界的大门!——live2d 博客园 个性化定制
  • 原文地址:https://www.cnblogs.com/emituofo/p/2769188.html
Copyright © 2020-2023  润新知