Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <math.h>
- #define CAPACITY 255
- int is_a_number(char c) {
- return ((c >= '0' && c <= '9') || c == '.' || c == 'e' || c == 'E') ? 1 : 0;
- }
- int op_precendence(char c) {
- switch (c) {
- case '(':
- return 2;
- case '+':
- case '-':
- return 3;
- case '*':
- case '/':
- return 4;
- case '^': //pow
- return 5;
- case '`': //sqrt
- //case '~': //exp
- case '!': //log
- case '@': //sin
- case '#': //cos
- case '$': //tan
- case '&': //sinh
- case '[': //cosh
- case ']': //tanh
- case '{': //asin
- case '}': //acos
- case ';': //atan
- return 1;
- default:
- return 0;
- }
- }
- char* convert_to_rpn(char *expr) {
- static char rpn_expr[CAPACITY];
- char stack[CAPACITY];
- char temp[CAPACITY];
- int i, j, k, l, depth;
- i = j = k = l = depth = 0;
- for (; expr[l] != '\0'; ++l) {
- if (!is_a_number(expr[l])) {
- int p = op_precendence(expr[l]);
- switch (p) {
- case 0:
- switch (expr[l]) {
- case ')':
- if (k) {
- for (int w = 0; w < k; ++w)
- rpn_expr[i++] = temp[w];
- rpn_expr[i++] = ' ';
- k = 0;
- }
- while (stack[--j] != '(' && j >= 0) {
- rpn_expr[i++] = stack[j];
- rpn_expr[i++] = ' ';
- }
- --depth;
- break;
- case ' ':
- break;
- default:
- temp[k++] = expr[l];
- }
- break;
- case 2:
- if (k) {
- temp[k] = '\0';
- if (!strcmp(temp, "sqrt")) stack[j++] = '`';
- //else if (!strcmp(temp, "exp")) stack[j++] = '~';
- else if (!strcmp(temp, "log")) stack[j++] = '!';
- else if (!strcmp(temp, "sin")) stack[j++] = '@';
- else if (!strcmp(temp, "cos")) stack[j++] = '#';
- else if (!strcmp(temp, "tan")) stack[j++] = '$';
- else if (!strcmp(temp, "sinh")) stack[j++] = '&';
- else if (!strcmp(temp, "cosh")) stack[j++] = '[';
- else if (!strcmp(temp, "tanh")) stack[j++] = ']';
- else if (!strcmp(temp, "asin")) stack[j++] = '{';
- else if (!strcmp(temp, "acos")) stack[j++] = '}';
- else if (!strcmp(temp, "atan")) stack[j++] = ';';
- k = 0;
- }
- else
- stack[j++] = expr[l];
- ++depth;
- break;
- case 3:
- case 4:
- case 5:
- if (k) {
- for (int w = 0; w < k; ++w)
- rpn_expr[i++] = temp[w];
- rpn_expr[i++] = ' ';
- k = 0;
- }
- while (op_precendence(expr[l]) <= op_precendence(stack[j - 1]) && j > 0) {
- rpn_expr[i++] = stack[--j];
- rpn_expr[i++] = ' ';
- }
- stack[j++] = expr[l];
- break;
- case 1:
- stack[j++] = expr[l];
- break;
- default:
- return "";
- }
- }
- else
- temp[k++] = expr[l];
- }
- for (int w = 0; w < k; ++w)
- rpn_expr[i++] = temp[w];
- rpn_expr[i++] = ' ';
- while (j > 0)
- rpn_expr[i++] = stack[--j];
- while (rpn_expr[i] == ' ') --i;
- rpn_expr[i] = '\0';
- return rpn_expr;
- }
- double convert_to_a_number(char *expr) {
- int i, extra, power, temp, sign;
- double num;
- i = num = extra = power = temp = 0;
- sign = 1;
- if (expr[i++] == '-')
- sign = -1;
- else
- --i;
- while (expr[i] != '\0') {
- if (expr[i] == '.') extra = 1;
- else if (expr[i] == 'e' || expr[i] == 'E') extra = 2;
- else if (extra == 2) {
- if (expr[i++] == '-') extra = -1;
- else extra = 1;
- while (expr[i] != '\0') {
- temp *= 10;
- temp += expr[i++] - '0';
- }
- }
- else {
- if (extra == 1) --power;
- num *= 10;
- num += expr[i] - '0';
- }
- ++i;
- }
- power += (extra * temp);
- return sign*num*pow(10, power);
- }
- double calculate(char *rpn_expr) {
- double stack[CAPACITY] = { 0 };
- char temp[CAPACITY];
- int i, j, k;
- double op1, op2;
- i = j = k = op1 = op2 = 0;
- while (rpn_expr[i] != '\0') {
- if (is_a_number(rpn_expr[i])) {
- temp[k++] = rpn_expr[i];
- }
- else {
- switch (rpn_expr[i]) {
- case ' ':
- if (k) {
- temp[k] = '\0';
- stack[j++] = convert_to_a_number(temp);
- }
- k = 0;
- break;
- case '+':
- op1 = stack[--j];
- op2 = stack[--j];
- stack[j++] = op2 + op1;
- break;
- case '-':
- op1 = stack[--j];
- op2 = stack[--j];
- stack[j++] = op2 - op1;
- break;
- case '*':
- op1 = stack[--j];
- op2 = stack[--j];
- stack[j++] = op2 * op1;
- break;
- case '/':
- op1 = stack[--j];
- op2 = stack[--j];
- stack[j++] = (double)op2 / op1;
- break;
- case '`':
- op1 = stack[--j];
- stack[j++] = sqrt(op1);
- break;
- case '!':
- op1 = stack[--j];
- stack[j++] = log(op1);
- break;
- case '@':
- op1 = stack[--j];
- stack[j++] = sin(op1);
- break;
- case '#':
- op1 = stack[--j];
- stack[j++] = cos(op1);
- break;
- case '$':
- op1 = stack[--j];
- stack[j++] = tan(op1);
- break;
- case '&':
- op1 = stack[--j];
- stack[j++] = sinh(op1);
- break;
- case '[':
- op1 = stack[--j];
- stack[j++] = cosh(op1);
- break;
- case ']':
- op1 = stack[--j];
- stack[j++] = tanh(op1);
- break;
- case '{':
- op1 = stack[--j];
- stack[j++] = asin(op1);
- break;
- case '}':
- op1 = stack[--j];
- stack[j++] = acos(op1);
- break;
- case ';':
- op1 = stack[--j];
- stack[j++] = atan(op1);
- break;
- default:
- return 0;
- }
- }
- ++i;
- }
- if (--j != 0) return 0;
- else return stack[j];
- }
- double parse(char *expr) {
- return calculate(convert_to_rpn(expr));
- }
- int main() {
- char line[CAPACITY];
- while (strcmp(line, "x")) {
- scanf("%s", line);
- printf("%f\n", parse(line));
- }
- getchar();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement