标签:sys main nbsp log pause 表达 优先级 ret 数字
1 #include<stdio.h> 2 #include<math.h> 3 #include<stdlib.h> 4 5 typedef struct stack1 { 6 char data[20]; 7 int top; 8 } StackChars; 9 10 typedef struct stack2 { 11 double data[20]; 12 int top; 13 } StackDatas; 14 15 double calculator(char str[100]); 16 char getUnary(char str[20], int * key); 17 int getLevel(char a); 18 void InitStackdata(StackDatas* sdt); 19 void InitStackchar(StackChars* stc); 20 void Pushd(StackDatas* stc, double x); 21 void Pushc(StackChars* stc, char x); 22 void Popd(StackDatas* sdt, double * y); 23 void Popc(StackChars* sdt, char * y); 24 void cal(StackDatas* sdt, char a); 25 double toData(char str[20], int* key); 26 int stackIn(char a, char top); 27 28 double calculator(char str[100]) { 29 StackChars stackCh; 30 StackDatas stackDa; 31 InitStackdata(&stackDa); 32 InitStackchar(&stackCh); 33 Pushc(&stackCh, ‘=‘); 34 int i = 0, sign = 1;/*sign标记是否是表达式最开始*/ 35 36 while (str[i] != ‘=‘&&str[i]) { 37 while (str[i] == ‘ ‘)i++; 38 if (sign && (str[i] == ‘+‘ || str[i] == ‘-‘)) 39 { 40 Pushd(&stackDa, 0);/*处理表达式或(后直接带的第一个正负号*/ 41 } 42 if (str[i] >= ‘0‘&&str[i] <= ‘9‘ || str[i] == ‘.‘) 43 { 44 Pushd(&stackDa, toData(str, &i));/*把字符转化操作数,并放入对应栈中*/ 45 sign = 0; 46 while (str[i] == ‘ ‘)i++; 47 } 48 else if (str[i] >= ‘a‘&&str[i] <= ‘z‘) 49 { 50 Pushc(&stackCh, getUnary(str, &i));/*单目运算符(不含括号)可直接放入栈中*/ 51 while (str[i] == ‘ ‘)i++; 52 } 53 else if (str[i] == ‘)‘) { 54 char x = ‘!‘; 55 while (stackCh.data[stackCh.top] != ‘(‘) {/*用括号中的操作符运算*/ 56 Popc(&stackCh, &x); 57 cal(&stackDa, x); 58 } 59 Popc(&stackCh, &x);/*删掉(不运算*/ 60 i++; 61 while (str[i] == ‘ ‘)i++; 62 } 63 else { 64 if (str[i] == ‘(‘) 65 sign = 1; 66 if (stackIn(str[i], stackCh.data[stackCh.top])) 67 Pushc(&stackCh, str[i]); 68 else { 69 int stop = 0, cur = stackCh.top; 70 while (!stop) 71 { 72 stackCh.top--; 73 cal(&stackDa, stackCh.data[cur]); 74 cur--; 75 stop = stackIn(str[i], stackCh.data[cur]); 76 } 77 Pushc(&stackCh, str[i]); 78 } 79 i++; 80 } 81 } 82 char x; 83 double result; 84 while (stackCh.data[stackCh.top] != ‘=‘) { 85 86 Popc(&stackCh, &x); 87 cal(&stackDa, x); 88 } 89 Popc(&stackCh, &x); 90 Popd(&stackDa, &result); 91 return result; 92 } 93 94 char getUnary(char str[20], int * key) { 95 char unary[6];/*记录单目运算符*/ 96 int j = 0; 97 while (str[*key] >= ‘a‘&&str[*key] <= ‘z‘) 98 { 99 unary[j++] = str[*key]; 100 (*key)++; 101 } 102 unary[j] = ‘\0‘; 103 if (strcmp(unary, "sin") == 0)return ‘s‘; 104 else if (strcmp(unary, "cos") == 0) return ‘c‘; 105 else if (strcmp(unary, "log") == 0) return ‘o‘; 106 else { if (strcmp(unary, "ln") == 0) return ‘n‘; } 107 108 } 109 110 int getLevel(char a) {/*得到操作符优先级,除了操作符外其他字符返回-1,对于数字和‘.‘的判断不用此函数*/ 111 switch (a) { 112 case‘=‘:return 0; 113 case‘+‘:return 1; 114 case‘-‘:return 1; 115 case‘*‘:return 2; 116 case‘/‘:return 2; 117 case‘^‘:return 2; 118 case‘s‘:return 3;/*sin*/ 119 case ‘c‘:return 3;/*cos*/ 120 case‘o‘:return 3;/*log*/ 121 case‘n‘:return 3;/*ln*/ 122 case‘(‘:return 4;/*‘(‘进入栈前为最大4,进入栈后为最小0*/ 123 default:return -1; 124 } 125 } 126 127 void InitStackdata(StackDatas* sdt) { 128 (*sdt).top = -1; 129 } 130 131 void InitStackchar(StackChars* stc) { 132 (*stc).top = -1; 133 } 134 135 void Pushd(StackDatas* stc, double x) { 136 (*stc).top++; 137 (*stc).data[(*stc).top] = x; 138 } 139 140 void Pushc(StackChars* stc, char x) { 141 (*stc).top++; 142 (*stc).data[(*stc).top] = x; 143 } 144 145 void Popd(StackDatas* sdt, double * y) { 146 *y = (*sdt).data[(*sdt).top]; 147 (*sdt).top--; 148 } 149 150 void Popc(StackChars* sdt, char * y) { 151 *y = (*sdt).data[(*sdt).top]; 152 (*sdt).top--; 153 } 154 155 156 void cal(StackDatas* sdt, char a) { 157 double top1 = (*sdt).data[(*sdt).top]; 158 double top2 = (*sdt).data[(*sdt).top - 1]; 159 double result = 0.0; 160 switch (a) { 161 case‘+‘:result = top1 + top2; 162 (*sdt).top--; 163 break; 164 case‘-‘:result = top2 - top1; 165 (*sdt).top--; 166 break; 167 case‘*‘:result = top2 * top1; 168 (*sdt).top--; 169 break; 170 case‘/‘:result = top2 / top1; 171 (*sdt).top--; 172 break; 173 case‘^‘:result = pow(top2, top1); 174 (*sdt).top--; 175 break; 176 case‘s‘:/*sin*/ 177 result = sin(top1); 178 break; 179 case ‘c‘:/*cos*/ 180 result = cos(top1); 181 break; 182 case‘o‘:/*log*/ 183 result = log10(top1); 184 break; 185 case‘n‘:/*ln*/ 186 result = log(top1); 187 break; 188 } 189 (*sdt).data[(*sdt).top] = result; 190 } 191 192 double toData(char str[20], int* key) { 193 char rel[20] = { ‘\0‘ }; 194 int i = 0; 195 while (str[*key] >= ‘0‘&&str[*key] <= ‘9‘ || str[*key] == ‘.‘) { 196 rel[i] = str[*key]; 197 i++; 198 (*key)++; 199 } 200 rel[i] = ‘\0‘; 201 return atof(rel); 202 } 203 204 int stackIn(char a, char top) {/*返回1 a可直接进栈*/ 205 int x = getLevel(a); 206 int y = getLevel(top); 207 if (top == ‘(‘)/*栈内(为0*/ 208 y = 0; 209 if (x <= y) 210 return 0;/*a不能直接进栈*/ 211 else 212 return 1; 213 } 214 215 216 217 int main() { 218 char str[100]; 219 while (1) {//这个我直接按叉号结束程序,有更好方法可以改 220 gets(str); 221 printf("%.4f \n", calculator(str));//按保留小数点后4位,可修改 222 } 223 224 system("pause"); 225 }
标签:sys main nbsp log pause 表达 优先级 ret 数字
原文地址:https://www.cnblogs.com/logcabin/p/12754878.html