华为OJ—四则运算

题目如下:

描述:
请实现如下接口
    /* 功能:四则运算
     * 输入:strExpression:字符串格式的算术表达式,如: "3+2*{1+2*[-4/(8-6)+7]}"
         * 返回:算术表达式的计算结果
     */
    public static int calculate(String strExpression)
    {
        /* 请实现*/
        return 0;
    } 
约束:
pucExpression字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。
pucExpression算术表达式的有效性由调用者保证; 
 
知识点
运行时间限制 10M
内存限制 128
输入
输入一个算术表达式
输出
得到计算结果
样例输入 3+2*{1+2*[-4/(8-6)+7]}
样例输出 25

解答要点:

1、需要将中缀表达式转换为后缀表达式后,然后按顺序进行计算;
2、需要注意数值可能出现负数。

代码

#include<string>
#include<stack>
#include<vector>
#include<iostream>
#include<sstream>

using namespace std;

// 四则运算,
//获得优先级
int getPriorty(char &c)
{
    switch(c)
    {
    case '{':
    case '[':
    case '(':
        return -1;
    case '+':
    case '-':
        return 0;
    case '*':
    case '/':
        return 1;
    case '}':
        return 2;
    case ']':
        return 3;
    case ')':
        return 4;
    }
}

//元素类,表示表达式中的一个元素(数值或者运算符),因为可能存在负数,故此处需要进行封装
typedef struct ELEMENT
{
    unsigned _type;            //元素类型,0表示元素,1表示运算符,-1表示无效
    int _value;                     //数值
    char _c_operation;        //运算符
    int _priority;                  //运算符优先级

    ELEMENT()
    {
        _type=-1;
    };

    ELEMENT(int value)
    {
        _type=0;
        _value=value;
    };

    ELEMENT(char c)
    {
        _type=1;
        _c_operation=c;
    }

    //打印输出
    static void print(vector<ELEMENT> datas)
    {
        for(size_t i=0; i<datas.size(); i++)
        {
            if(datas[i]._type==-1)
                continue;
            else if(datas[i]._type==0)
            {
                if(datas[i]._value<0)
                    cout<<"("<<datas[i]._value<<")";
                else
                    cout<<datas[i]._value;
                continue;
            }
            else if(datas[i]._type==1)
            {
                cout<<datas[i]._c_operation;
                continue;
            }
        }
        cout<<endl;
    }

    //将结构转化为字符串
    static void elements2string(vector<ELEMENT> &datas,string &strResult)
    {
        ostringstream out;
        for(size_t i=0; i<datas.size(); i++)
        {
            if(datas[i]._type==-1)
                continue;
            else if(datas[i]._type==0)
            {
                if(datas[i]._value<0)
                    out<<"("<<datas[i]._value<<")";
                else
                    out<<datas[i]._value;
                continue;
            }
            else if(datas[i]._type==1)
            {
                out<<datas[i]._c_operation;
                continue;
            }
        }
        strResult=out.str();
    }
} Element;

//string 转int
inline int string2int(string &str)
{
    istringstream sitemp(str);
    int temp;
    sitemp>>temp;
    return temp;
}

//中缀表达式转后缀表达式
//读入表达式,如果是数字则入队(element)
//如果是运算符,比较运算符与栈顶运算符的优先级,如果栈顶运算符的优先级大于等于当前运算符,则将栈顶运算符出栈入队直到栈顶运算符优先级小于等于
//          当前运算符为止,然后将当前运算符入栈;否则当前运算符直接入栈
//          “{}”“()”的优先级是最高的,“{”或“(”只有在遇到“}”“)”才出栈
void infix2postfixEx(string &strInFix, vector<Element> &elements)
{
    stack<char> stOperation;    //运算符栈
    for(size_t i=0; i<strInFix.length(); i++)
    {
        char c=strInFix[i];
        if(c<'0'||c>'9')//如果是运算符
        {
            if(c=='-')//如果运算符是'-',其有可能是负号标志,也有可能是减号
            {
                if(i==0||
                        strInFix[i-1]=='{'||strInFix[i-1]=='['||strInFix[i-1]=='('||strInFix[i-1]=='*'||strInFix[i-1]=='/'||
                        strInFix[i-1]=='+'||strInFix[i-1]=='-') //如果'-'是第一位或者'-'前面是*,/,{,[,(,+,- 。说明该'-'表示的是负号;否则表示正常的运算符
                {
                    string str=string(1,c)+strInFix[++i];
                    int temp=string2int(str);
                    elements.push_back(Element(temp));
                    continue;
                }
            }

            if(stOperation.empty())
                stOperation.push(c);
            else
            {
                if(c=='{'||c=='['||c=='(')
                {
                    stOperation.push(c);
                    continue;
                }
                else if(c==')')
                {
                    while(stOperation.top()!='(')
                    {
                        elements.push_back(Element(stOperation.top()));
                        stOperation.pop();
                    }
                    stOperation.pop();
                    continue;
                }
                else if(c=='}')
                {
                    while(stOperation.top()!='{')
                    {
                        elements.push_back(Element(stOperation.top()));
                        stOperation.pop();
                    }
                    stOperation.pop();
                    continue;
                }
                else if(c==']')
                {
                    while(stOperation.top()!='[')
                    {
                        elements.push_back(Element(stOperation.top()));
                        stOperation.pop();
                    }
                    stOperation.pop(); //弹出'['
                    continue;
                }

                if(getPriorty(stOperation.top())<getPriorty(c))     //栈顶运算符优先级小于当前运算符,则将当前运算符入栈
                    stOperation.push(c);
                else//栈顶运算符优先级大于等于当前运算符,则将栈顶运算符出栈入队,直到栈顶运算符优先级小于当前运算符为止
                {
                    while(!stOperation.empty()&&getPriorty(stOperation.top())>=getPriorty(c))
                    {
                        elements.push_back(Element(stOperation.top()));
                        stOperation.pop();
                    }
                    stOperation.push(c);
                }
            }
        }
        else  //如果是数字,则直接入队
        {
            string str=string(1,c);
            int temp=string2int(str);
            elements.push_back(Element(temp));
        }
    }
    while(!stOperation.empty())
    {
        elements.push_back(Element(stOperation.top()));
        stOperation.pop();
    }
    //Element::print(elements);
}

void calculate(string &strInFix,string &strOutResult){

    vector<Element> elements;//后缀表达式
    infix2postfixEx(strInFix,elements);

    //根据后缀表达式进行计算
    stack<int> datas;
    for(auto &t:elements){
        if(t._type==0)
            datas.push(t._value);
        else if(t._type==1){
            auto t1=datas.top();
            datas.pop();
            auto t2=datas.top();
            datas.pop();
            if(t._c_operation=='+')
                 datas.push(t2+t1);
            else if(t._c_operation=='-')
                datas.push(t2-t1);
            else if(t._c_operation=='*')
                datas.push(t2*t1);
            else if(t._c_operation='/')
                datas.push(t2/t1);
        }
    }

    ostringstream    out;
    out<<datas.top();
    strOutResult=out.str();
}

int main()
{
    string str,strPostFix;
    getline(cin,str);
    calculate(str,strPostFix);
    cout<<strPostFix;
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华为OD机试是华为公司的在线笔试平台,用于选拔人才。根据题库的不同版本,2023年A、B版本的真题目录大致如下: 考点分类: 1. 数据结构算法:包括数组、链表、栈、队列、树、图、排序算法、查找算法等。 2. 编程语言:主要考察C++或Java语言的基础知识,包括语法、数据类型、运算符、流程控制等。 3. 计算机网络:主要考察网络基础知识,包括HTTP、TCP/IP协议、网络安全等。 4. 操作系统:主要考察操作系统的基础知识,包括进程管理、内存管理、文件系统等。 5. 数据库:主要考察数据库基础知识,包括SQL语句的编写、数据库设计等。 6. 算法设计与分析:主要考察算法的设计思路和复杂度分析能力。 7. 编程综合能力:主要考察应聘者的编程能力和解决问题的能力,题目可能是一些综合性的编程题目。 在线OJ入口: 华为OD机试一般提供在线提交代码的平台,应聘者需要在平台上注册账号,并按照要求进行代码的提交与运行。具体的OJ入口链接将根据考试安排提供给应聘者,一般将在笔试前一段时间内向应聘者发送相关信息。 在进行华为OD机试的过程中,应聘者可以根据真题目录中的考点分类进行有针对性的复习和准备,熟悉相关知识点,并通过刷题进行练习来提高自己的编程能力和解题能力。希望以上信息能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值