昨天晚上写完《计算用字符串表示的个位数四则运算的值(栈)》,自己给自己留了个问题?即,怎样计算用字符串表示的整数四则运算的值。这里增加了两个难度,整数的位数不再是一位,而且表达式中可以含括号。下面给出代码:
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 }
运行结果就不贴了,感兴趣的朋友,可以自己试试。
不足之处,欢迎交流。