2017 CVTE春招内推专场 C/C++软件开发岗笔试编程题(第二场)

这次我用别人的号考的,只为刷刷题。

这次选择题比上次的简单一些,讲真。不过第二道编程题比上一场的复杂了不少,但是对于做过这种题目的人应该不难。

第一题是设计一种排序方法,对于给定的一个数组,将偶数放前面,奇数放后面。

如 {6, 4, 1, 8, 3, 5} ,其中一种输出是 {6, 4, 8, 1, 3, 5}。答案有多种,只要满足“偶数在前,奇数在后”即可。

我的做法是用两个vector,分别存储偶数和奇数,再将两个vector合并,复杂度为O(n),代码就不上了。

 

第二题是表达式计算:

给定一个中缀表达式,如:“10+2.5*(3+1)-5”,输出表达式的计算结果,假定表达式均为正确输入,数字可能为整数也可能为浮点数,操作符只有'+', '-', '*', '/', '(', ')'。

解法就是中缀表达式转后缀表达式,转换算法可自行百度,当然我的代码中也有注释:

  1 #include <iostream>
  2 #include <string>
  3 #include <queue>
  4 #include <stack>
  5 #include <map>
  6 #include <functional>
  7 #include <cmath>
  8 #include <cstring>
  9 
 10 using namespace std;
 11 
 12 // 字符串转double 
 13 double toDouble(string str)
 14 {
 15     double num;
 16     int num1 = 0;
 17     int num2 = 0;
 18     int length = str.size();
 19     int dotIndex = str.find(".");
 20     if (dotIndex < 0 || dotIndex >= length)
 21     {
 22         for (int i = 0; i < length; ++i)
 23             num1 = num1 * 10 + static_cast<int>(str[i] - '0');
 24 
 25         num = num1;
 26     }
 27     else
 28     {
 29         for (int i = 0; i < dotIndex; ++i)
 30             num1 = num1 * 10 + static_cast<int>(str[i] - '0');
 31 
 32         for (int i = dotIndex + 1; i < length; ++i)
 33             num2 = num2 * 10 + static_cast<int>(str[i] - '0');
 34 
 35         num = num1;
 36         num += 1.0 * num2 / pow(10, length - dotIndex - 1);
 37     }
 38     return num;
 39 }
 40 
 41 double getResult(char *expr, int length)
 42 {
 43     // 运算符优先级 
 44     map<char, int> prior;
 45     prior['*'] = prior['/'] = 2;
 46     prior['+'] = prior['-'] = 1;
 47     prior['#'] = 0;
 48 
 49     // C++11特性:function和lambda表达式 , 编译时记得加上参数 "-std=c++11" 
 50     map<string, function< double (double, double)> > binop;
 51     binop["+"] = [] (double a, double b) { return a + b; };
 52     binop["-"] = [] (double a, double b) { return a - b; };
 53     binop["*"] = [] (double a, double b) { return a * b; };
 54     binop["/"] = [] (double a, double b) { return a / b; };
 55 
 56     queue<string> rpn; // 后缀表达式(逆波兰式) 
 57     stack<string> st;  // 缓存操作符 
 58     st.push("#");      // 用来垫底,防止出现栈为空是的非法操作:st.top() 
 59     int i = 0;
 60     string token;
 61     while (i < length) // 转后缀表达式
 62     {
 63         token = "";
 64         
 65         // 如果是数字,直接放进表达式rpn  
 66         if (expr[i] >= '0' && expr[i] <= '9' || expr[i] == '.')
 67         {
 68             while (expr[i] >= '0' && expr[i] <= '9' || expr[i] == '.')
 69                 token += expr[i++];
 70             rpn.push(token);
 71         }
 72         // 如果是'(',直接入栈 
 73         else if (expr[i] == '(')
 74         {
 75             token = expr[i++];
 76             st.push(token);
 77         }
 78         // 如果是')',将栈顶的元素逐个加入表达式rpn 
 79         else if (expr[i] == ')')
 80         {
 81             string op = st.top();
 82             while (op != "(")
 83             {
 84                 rpn.push(op);
 85                 st.pop();
 86                 op = st.top();
 87             }
 88             st.pop();
 89             ++i;
 90         }
 91         // 如果是'+', '-', '*', '/',分两种情况处理 
 92         else
 93         {
 94             token = expr[i];
 95             
 96             // 如果st栈顶为'(',则直接将操作符压栈 
 97             if (st.top() == "(")
 98                 st.push(token);
 99 
100             // 否则,将栈顶所有优先级大于等于当前token的运算符('+', '-', '*', '/') 加入表达式rpn末尾 
101             else
102             {
103                 string op = st.top();
104                 while (prior[op[0]] >= prior[expr[i]])
105                 {
106                     rpn.push(op);
107                     st.pop();
108                     op = st.top();
109                 }
110                 st.push(token); 
111             }
112             ++i;
113         }
114     }
115     while (st.size() > 1)
116     {
117         rpn.push(st.top());
118         st.pop();
119     }
120 
121     /**
122      * --以下为计算过程-- 
123      * 后缀表达式计算规则:
124      * 操作数直接入栈
125      * 遇到操作符,则在栈顶取出两个操作数做相应的运算 
126      */ 
127     stack<double> ans;
128     string temp;
129     double op1, op2, res;
130     while (!rpn.empty())
131     {
132         temp = rpn.front();
133         if (temp[0] >= '0' && temp[0] <= '9')
134         {
135             ans.push(toDouble(temp));
136         }
137         else
138         {
139             op2 = ans.top();
140             ans.pop();
141             op1 = ans.top();
142             ans.pop();
143             res = binop[temp](op1, op2);
144             ans.push(res);
145         }
146         rpn.pop();
147     }
148     return ans.top();
149 }
150 
151 int main()
152 {
153     char *expr = "10+2.5*(3+1)-5";
154     cout << getResult(expr, strlen(expr)) << endl;
155 }

 

posted on 2017-03-04 22:18  松下风  阅读(370)  评论(0编辑  收藏  举报

导航