整理自我在騎魔滋事家哄騙小朋友的作業
話說有一陣子竟然變成月經題

這個程式可以處理像是
2+11.5*3
180+(9*12-6)

之類的算式
可處理括號和運算優先權,但不會處理syntax error和runtime error(例如div by 0)

轉載請註明出處
如果發現bug或有更好的改進意見,請讓我知道

// design by novus 2008
// some right reserved
#include <stdio.h>
#include <stdlib.h>

double Eval2(char *expr, char **end) {
    double Eval0(char*, char**);
    double res=0;
    if (*(*end=expr) == '(') {
        res = Eval0(*end+1, end);
    if (**end == ')') ++*end;
    } else { res=strtod(*end, end); }
    return res;
}

double Eval1(char* expr, char** end) {
    double res = Eval2(expr, end);
    while (**end=='*' || **end=='/')
        (**end=='*')? (res*=Eval2(*end+1, end)): (res/=Eval2(*end+1, end));
    return res;
}

double Eval0(char* expr, char** end) {
    double res = Eval1(expr, end);
    while (**end=='+' || **end=='-')
        res +=(**end=='+')? Eval1(*end+1, end): -Eval1(*end+1, end);
    return res;
}

int main() {
    char expr[128]={0}, *pos=0;
    printf("Exp : ");
    scanf("%s", expr);
    printf("Ans : %f\n", Eval0(expr, &pos));
}

//****** 2009-jun-06 ******

上面的程式可是純純正正的C++

因為有人抱怨欠缺C++味,所以另外推出C++風味餐

// design by novus 2009
// some right reserved
#include <iostream>
#include <cstdlib>

using namespace std;

double Eval2(istream& iss) {
    double Eval0(istream& iss);
    double res=0;
    if (iss.peek() == '(' && iss.get()) {
        res = Eval0(iss);
        iss.peek() == ')' && iss.get();
    } else { iss >> res; }
    return res;
}

double Eval1(istream& iss) {
    double res = Eval2(iss);
    while (iss.peek() == '*' || iss.peek() == '/')
        (iss.get() == '*')? (res*=Eval2(iss)): (res/=Eval2(iss));
    return res;
}

double Eval0(istream& iss) {
    double res = Eval1(iss);
    while (iss.peek() == '+' || iss.peek() == '-')
        res +=(iss.get() == '+')? Eval1(iss): -Eval1(iss);
    return res;
}

int main() {
    cout << Eval0(cin) << endl;
    system("pause");
}


arrow
arrow
    全站熱搜

    novus 發表在 痞客邦 留言(7) 人氣()