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 }