2019网易实习笔试题——给字符串定义符号运算(下)

2019网易实习笔试题——给字符串定义符号运算(上)
下面的代码参考了这位大神的:吾落凡

//判断是否为括号
bool isPra(string c)       //为了统一,采用字符串操作
{
    if (c == "(" || c == ")")
        return true;
    else
        return false;
}

//获得符号的优先性
int getPri(char c)
{
    switch (c)       //返回值代表不同的优先级
    {
    case '+':
    case '-':
        return 0;    //如果是加减,返回0
        break;
    case '*':
    case '/':
        return 1;    //如果是乘除,返回1
        break;
    case '!':      //如果是逆置或者 大写变小写,返回2
    case '~':
        return 2;
        break;
    case '(':
    case ')':
        return -1;    //注意,这里将括号设为最低优先级,因此括号不会被弹出,除非遇到右括号
        break;
    }
}

//判断符号的优先性
void check(string c, stack<string> &coll2, deque<string> &string_suffix)
{
    if (coll2.empty())
    {
        coll2.push(c);
        return;
    }

    if (isPra(c))
    {
        if (c == "(")
            coll2.push(c);
        else
        {
            //弹出所有元素直到遇到左括号
            while (coll2.top() != "(")
            {
                string ch = coll2.top();
                string_suffix.push_back(ch);
                coll2.pop();
            }

            //当遇到左括号时,弹出但不加入coll3(后缀表达式中)
            coll2.pop();
        }
    }
    else //如果不是括号
    {
        //取出栈顶元素,与当前符号进行优先性比较
        string sym = coll2.top();

        char c_temp = c[0];              //因为字符串的长度只为 1,所以采用这种方法将字符串转化为字符,用于后续比较操作符的优先级
        char sym_temp = sym[0];

        //比较两符号的优先性
        if (getPri(c_temp) <= getPri(sym_temp))
        {
            //如果c的优先性比栈顶符号小或等于,弹出栈顶元素
            coll2.pop();
            //并将其压入string_suffix(后缀表达式)中
            string_suffix.push_back(sym);
            //递归调用check,比较当前符号c与下一个栈顶符号的优先性
            check(c, coll2, string_suffix);
        }
        else
        {
            //如果c比栈顶符号优先级大,那将c压入coll2(操作符栈)中
            coll2.push(c);
        }
    }
}

//从coll中取出元素,分配元素到coll2和coll3中
void allocate(deque<string> &s_string, stack<string> &coll2, deque<string> &string_suffix)                //生成后缀表达式
{
    while (!s_string.empty())
    {
        string c = s_string.front();
        s_string.pop_front();

        if (c.size()!=1)
        {
            string_suffix.push_back(c);
        }
        else
        {
            //调用check函数,针对不同情况作出不同操作
            check(c, coll2, string_suffix);
        }
    }

    //如果输入结束,将coll2的元素全部弹出,加入后缀表达式中
    while (!coll2.empty())
    {
        string c = coll2.top();
        string_suffix.push_back(c);
        coll2.pop();
    }
}



//计算后缀表达式
void calculate(deque<string> &string_suffix, stack<string> &string_result)                // string_suffix 存放的是后缀表达式     string_result 是存放计算结果的
{
    while (!string_suffix.empty())
    {
        string c = string_suffix.front();
        string_suffix.pop_front();

        //如果是操作数,压入栈中

        if (c.size() != 1)
        {   
            string_result.push(c);
        }
        else //如果是操作符,从栈中弹出元素进行计算
        {
            char c_temp = c[0];
            string op1 = string_result.top();
            string_result.pop();

            if (c_temp == '!' || c_temp == '~')                //一元操作符
            {
                if (c_temp == '!')
                {
                     string_reverse(op1);
                     string_result.push(op1); 
                }
                else
                {
                    string_tochange(op1);
                    string_result.push(op1);

                }
            }
            else                                             //二元操作符
            {
                string op2 = string_result.top();
                string_result.pop();
                switch (c_temp)                            //根据运算符调用不同的函数
                {
                case '+':
                    string_add(op2, op1);                      //在计算后缀表达式的时候,如果对两个数的顺序有要求的话,一定要按照输入的顺序进行操作,那么后取出来的数是在前面的
                    string_result.push(op2);
                    break;
                case '-':
                    string_minus(op2, op1);
                    string_result.push(op2);
                    break;
                case '*':
                    string_multiplication(op2, op1);
                    string_result.push(op2);
                    break;
                case '/':
                    string_division(op2, op1);
                    string_result.push(op2);
                    break;
                    //case '!':
                    //  string_result.push(op2);                    //一元操作符,所以需要把第二个元素压入栈中,后来发现这个错误的,当你的一元操作符在最前面的是,此时的 string_result 中只有一个元素,在进行弹出第二个元素的时候,会报错
                    //  string_reverse(op1);
                    //  string_result.push(op1);
                    //  break;
                    //case '~':
                    //  string_result.push(op2);
                    //  string_tochange(op1);
                    //  string_result.push(op1);
                    //  break;
                }

            }

        }
    }
}

主函数

int main()
{


    deque<string> s_string;          //盛放中缀表达式
    stack<string> coll2;     
    deque<string> string_suffix; //盛放后缀表达式
    stack<string> string_result; //计算后缀表达式的辅助容器
    string s;
    cin >> s;

    for (int i = 0; i < s.size();)
    {
        string temp;
        while (s[i] >= 'A' && s[i] <= 'Z' || s[i] >= 'a' && s[i] <= 'z')       //如果s[i] 是字母
            temp = temp + s[i++];
        if (!temp.empty())
            s_string.push_back(temp);
        else
        {
            temp = s[i++];
            s_string.push_back(temp);
        }           
    }

    allocate(s_string, coll2, string_suffix);      //从s_string中取出元素,得到后缀表达式 string_suffix 中
    calculate(string_suffix, string_result);               //计算后缀表达式
    cout << string_result.top() << endl;
    system("pause");
    return 0;

}

计算结果
(ABC+EDF*jhi)/ABC-jhi ——》 EDjhiF
(!WER+~TY+ABC+EDF*jhi)/ABC-jhi ——》 REWtyEDjhiF

你可能感兴趣的:(C++)