华为机试HJ50:四则运算

简介: 华为机试HJ50:四则运算

题目描述:

输入一个表达式(用字符串表示),求这个表达式的值。

保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。

输入描述:

输入一个算术表达式

输出描述:

得到计算结果

示例:

输入:

3+2*{1+2*[-4/(8-6)+7]}


输出:

25

解题思路:

这道题如果用Python做挺简单的,但是用C++没有现成的函数调用,只能自己来写四则运算函数了。Calculation函数完成四则运算,其逻辑大致如下:


首先判断式子两端是否有括号,若正好两侧有,则前后缩进,计算内部公式;再判断内部公式中最后出现的计算符(加减和乘除)位置,若有加减则先算加减,然后分别将计算符前后的内容用Calculation计算,依次递归;直到某一层内容不存在计算符,即只有数字内容,用stoi函数将其转换为整型,进行计算,完成。


注意,在上述逻辑中有一个flag,它的意义在于判断是否有多层括号,比如公式为((5+3)),其内部式子为(5+3),在分析其内容时,因为两侧有括号包围,所以am和md都为0,此时如果直接用stoi就会失效,那么就将start和end往里缩进一层,调用Calculation,这样就实现了多层括号的识别。

测试代码:

#include <string>
#include <vector>
#include <iostream>
using namespace std;
int Calculation(string& exp, int start, int end) 
{
    // 判断是否有括号,若两端包围则计算内部
    if ((exp[start] == '(' || exp[start] == '[' || exp[start] == '{') &&
        (exp[end-1] == ')' || exp[end-1] == ']' || exp[end-1] == '}')) 
    {
        vector<int> vec;
        for (int i = start; i < end-1; ++i) 
        {
            if (exp[i] == '(' || exp[i] == '[' || exp[i] == '{') 
                vec.push_back(i);
            else if (exp[i] == ')' || exp[i] == ']' || exp[i] == '}') 
                vec.pop_back();
        }
        if (vec.back() == start) 
        { 
            ++start; 
            --end; 
        }
    }
    int layer = 0, am = 0, md = 0;
    bool flag=false;                // 判断是否有内置括号
    // 标记最后出现的加减乘除号位置(不在括号内)
    for (int i = start; i < end; ++i) 
    {
        if (exp[i] == '(' || exp[i] == '[' || exp[i] == '{') 
        {
            ++layer;
            flag=true;
        }
        else if (exp[i] == ')' || exp[i] == ']' || exp[i] == '}') 
        {
            --layer;
            flag=true;
        }
        else if ((exp[i] == '+' || exp[i] == '-') && !layer) 
            am = i;
        else if ((exp[i] == '*' || exp[i] == '/') && !layer) 
            md = i;
    }
    // 若有加减号,则将符号前面的内容和后面的内容相加或减
    if (am > start) {
        if (exp[am] == '+') 
            return Calculation(exp, start, am) + Calculation(exp, am+1, end);
        else 
            return Calculation(exp, start, am) - Calculation(exp, am+1, end);
    } 
    // 若有乘除号,则将符号前面的内容和后面的内容相乘或者除
    else if (md > start) 
    {
        if (exp[md] == '*') 
            return Calculation(exp, start, md) * Calculation(exp, md+1, end);
        else 
            return Calculation(exp, start, md) / Calculation(exp, md+1, end);
    } 
    // 若没有加减乘除,还要判断下是否有内置括号,比如((5+3)),若有则往里缩进
    else if(flag)
    {
        return Calculation(exp, start+1, end-1);
    }
    // 若没有加减乘除,也没有内置括号,说明这部分内容是数字
    else
        return stoi(exp.substr(start, end-start));
}
int main() {
    string str;
    while (cin >> str) 
    {
        cout << Calculation(str, 0, str.size()) << endl;
    }
}


相关文章
|
人工智能
华为机试HJ26:字符串排序
华为机试HJ26:字符串排序
|
算法
华为机试HJ14:字符串排序
华为机试HJ14:字符串排序
|
算法
华为机试HJ108:求最小公倍数
华为机试HJ108:求最小公倍数
101 1
华为机试HJ96:表示数字
华为机试HJ96:表示数字
110 1
|
容器
华为机试HJ102:字符统计
华为机试HJ102:字符统计
163 1
华为机试HJ107:求解立方根
华为机试HJ107:求解立方根
148 1
华为机试HJ103:Redraiment的走法
华为机试HJ103:Redraiment的走法
184 2
|
容器
华为机试HJ89:24点运算
华为机试HJ89:24点运算
139 0
|
测试技术
华为机试HJ5:进制转换
华为机试HJ5:进制转换
108 0