表达式求值

这篇博客介绍了两种计算数学表达式值的方法。第一种使用数组存储数值和运算符,通过栈来处理运算优先级,实现表达式求解。第二种方法采用结构体`num_stk`和`ops_stk`分别存储数值和运算符,同样利用栈的特性处理运算符优先级。这两种方法都是解决计算数学表达式问题的有效途径。
摘要由CSDN通过智能技术生成

数组求解

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 * 返回表达式的值
 * @param s string字符串 待计算的表达式
 * @return int整型
 */
int solve(char* s ) {
    // write code here

    int len=strlen(s),num_stk[108], num_idx=-1,sign_idx=-1,op=0,op_l,op_r;
    char sign_stk[108],ch;
    for(int i=0;i<len;i++)
    {
        if((ch=s[i])>='0'&&ch<='9')
        {
            op=ch-48;
            int j=i+1;
            while(j<len&&(ch=s[j])>='0'&&ch<='9')//两位数及以上的读取
            {
                op=10*op+ch-48;
                j++;
            }
            i=j-1;//最后一次j++并没有读取
            num_stk[++num_idx]=op; 
            continue;
        }
        if(ch=='+'||ch=='-')
        {
            if(!i)//i==0
            {
                num_stk[++num_idx]=0;
                sign_stk[++sign_idx]=ch;
                continue;
            }
            while(sign_idx!=-1&&sign_stk[sign_idx]!='(')//访问sign_stk[]栈内的符号
            {
                op_r=num_stk[num_idx--];//访问num_stk[]第一个数字
                op_l=num_stk[num_idx];//访问num_stk[]第二个数字
                switch(sign_stk[sign_idx--])
                {
                    case '+':{num_stk[num_idx]=op_l+op_r;break;}
                    case '-':{num_stk[num_idx]=op_l-op_r;break;}
                    case '*':{num_stk[num_idx]=op_l*op_r;break;}
                }
            }
            sign_stk[++sign_idx]=ch;
            continue;
        }
        if(ch=='*')
        {
            if(sign_stk[sign_idx]=='*')
            {
                op_r=num_stk[num_idx--];
                op_l=num_stk[num_idx];
                num_stk[num_idx]=op_l*op_r;
                sign_idx--;
            }
            sign_stk[++sign_idx]='*';
            continue;
        }
        if(ch=='(')
        {
            sign_stk[ ++sign_idx ] = '('; 
            continue;
        }
        while(sign_stk[sign_idx]!='(')//前面用了三个if,说明ch不是数字,也不是"+"、"-"、"*"、"(",此时ch只能是")"
        {
            op_r = num_stk[ num_idx-- ];
            op_l = num_stk[num_idx];
            switch(sign_stk[ sign_idx-- ])
            {
                case '+' : { num_stk[num_idx] = op_l+op_r;   break; }
                case '-' : { num_stk[num_idx] = op_l-op_r;   break; }
                case '*' : { num_stk[num_idx] = op_l*op_r;   break; }
            }
        }
        sign_idx--;//虽然没有存进")",但是已经存了"(",需要消去(前面三个if都有continue,不会进入这个语句)
    }
    while(sign_idx != -1)//最后一个存入的是数字,导数第二存入符号时并不知道最后一个数字的值,所以再进行一次计算
    {
        op_r = num_stk[ num_idx-- ];
        op_l = num_stk[num_idx];
        switch(sign_stk[ sign_idx-- ])
        {
            case '+' : { num_stk[num_idx] = op_l+op_r;   break; }
            case '-' : { num_stk[num_idx] = op_l-op_r;   break; }
            case '*' : { num_stk[num_idx] = op_l*op_r;   break; }
        }
    }
    return num_stk[0];
}

结构体求解

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 * 返回表达式的值
 * @param s string字符串 待计算的表达式
 * @return int整型
 */
#define SIZE 10

struct num_stk {
    int data[SIZE];
    int top;
};

struct ops_stk {
    char data[SIZE];
    int top;
};

void push_num (struct num_stk *s, int item) {
    s->data[s->top] = item;
    s->top++;
}

void push_ops (struct ops_stk *s, char item) {
    s->data[s->top] = item;
    s->top++;
}

int pop_num (struct num_stk *s) {
    s->top--;
    return s->data[s->top];
}

char pop_ops (struct ops_stk *s) {
    s->top--;
    return s->data[s->top];
}

int priority (char c) {
    if (c == ')')
        return 0;
    else if (c == '*' || c == '/')
        return 1;
    else if (c == '+' || c == '-')
        return 2;
    else if (c == '(')
        return 3;
    else
        return -1;
}

int operate (int a, int b, char c) {
    if (c == '+')
        return a + b;
    else if (c == '-')  
        return b - a;
    else if (c == '*')
        return a * b;
    else if (c == '/')
        return a / b;
    else
        return -1;
}

int solve (char* s) {
    struct ops_stk *ops = (struct ops_stk*) malloc (sizeof (struct ops_stk));
    struct num_stk *nums = (struct num_stk*) malloc (sizeof (struct num_stk));
    
    ops->top = 0;
    nums->top = 0;
    
    char *ptr = s, ch;
    int a, b;
    int val;
    
    while (*ptr != '\0') {
        // write code here
        if (*ptr >= '0' && *ptr <= '9') {
            val = 0;
            while (*ptr >= '0' && *ptr <= '9') {
                val = 10 * val + *ptr - 48;
                ptr++;
            }
            push_num (nums, val);
            ptr--;
        }
        else {
            if (*ptr == '(')
                push_ops (ops, *ptr);
            if (*ptr == ')') {
                ch = pop_ops (ops);
                while (ch != '(') {
                    a = pop_num (nums);
                    b = pop_num (nums);
                    push_num (nums, operate (a, b, ch));
                    ch = pop_ops (ops);
                }
            }
            if (*ptr == '+' || *ptr == '-' || *ptr == '*' || *ptr == '/') {
                while (ops->top > 0 && (priority (*ptr) >= priority (ops->data[ops->top - 1]))) {//priority越小优先级越高
                    a = pop_num (nums);
                    b = pop_num (nums);
                    push_num (nums, operate (a, b, pop_ops (ops)));
                }
                push_ops (ops, *ptr);
            }
        }
        ptr++;
    }
    
    
    while (ops->top > 0) {
        a = pop_num (nums);
        b = pop_num (nums);
        push_num (nums, operate (a, b, pop_ops (ops)));
    }
    
    return pop_num (nums);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值