2-【软件雏鹰计划-Java版】第二周编程题目练习题解
表达式计算
题目
四则运算表达式可用表达式树来表达,如图所示。 图中最右边部分是该表达式树的后序遍历(后序遍历是指先遍历左子树,再遍历右子树,最后访问节点本身,简写 LRN)。
现给你一个字符串,代表一个后序遍历形式的四则运算表达式,请计算出表达式的结果(只输出整数部分)。
注:
- 都是双目运算,不存在单目运算;
- 中间计算结果范围:[-2^31, 2^31);
- 除法只需保留整数部分,比如:5/4=1, (-5)/3=-1, 5/(-3)=-1,无需考虑余数;无需考虑除数为0的情况,用例不存在除零。
时间限制: C/C++ 1000ms, 其他语言:2000ms
内存限制: C/C++ 64MB, 其他语言:128MB
输入
一个字符串,代表一个四则运算表达式,由若干操作数和运算符组成,操作数、运算符之间都用一个逗号隔开。长度范围:[1,50000)。
注:用例保证输入合法:1)一定有计算结果; 2)操作数是合法的整数; 3)运算符只包含+
,-
,*
,/
四种。
输出
一个整数,表示表达式的计算结果,用例保证最终结果范围:-2,147,483,648 ~ 2,147,483,647。
样例1
1 | 输入: |
样例2
1 | 输入: |
本质上是计算逆波兰表达式(a.k.a 后缀表达式),常规的数学计算式是中缀表达式
后缀表达式的好处在于不需要括号来表示优先级,以及一次从左到右的顺序遍历即可计算出答案,具体的计算流程在维基百科已经很解释的很清楚了,只需要把伪代码实现一下就可以了
引自维基百科:
- while 输入
- 读取下一个字符X
- 如果X是数字
- 将X入栈
- 反之如果X是操作符
- 根据操作符的目数从栈中取出指定数量的数字(加减乘除都只取出两个)
- 计算操作结果
- 将操作结果再次入栈
在保证输入表达式正确的情况下,遍历完表达式后,栈里应当只有一个数字,即为整个表达式的运算结果
1 | private static int calcExpression(String expression) { |
话单发送
题目
某核心网设备向计费网关发送话单(一个话单指一条通话记录的信息),发送规则如下:
- 每个话单具有长度和优先级两个属性,优先级值越小表示优先级越高,高优先级的发送完,才能发送次优先级的。
- 设备有一个承载规格,表示发送话单总容量的阈值,发送话单的总长度不能超过承载规格。
现给定设备的承载规格和待发送话单(长度和优先级)列表,请计算最多可以发送多少个话单。
时间限制: C/C++ 1000ms, 其他语言:2000ms
内存限制: C/C++ 256MB, 其他语言:512MB
输入
第一行是正整数 cap ,表示设备的承载规格,取值范围:[1,10000]
第二行是正整数 num ,表示待发送话单的数量,取值范围:[0,100]
第三行 num 个整数,依次表示每个待发送话单的长度,每个值的范围:[0, 1000]
第四行 num 个整数,依次表示每个待发送话单的优先级,每个值的范围:[0,30]
第三行和第四行的数据一一对应,表示同一个话单的长度和优先级。
输出
输出一个整数,表示最多能发送话单的个数。
样例1
1 | 输入: |
任务调度算法,和CI调度不同的是,这里没有要求相同优先级的按什么顺序发送,因此对于优先度相同的话单,我们直接优先按长度小的发送,即可保证发送数量最多
把bill数组转换为一个List<Bill>,然后按照优先级升序,长度升序排序即可
顺序遍历bills,并维护当前设备剩余的阈值和已发送的话单数量,直至剩余阈值无法继续发送新的话单即可返回结果
1 | private static int getMaxSendNumber(int cap, int[] billLen, int[] billPrior) { |
字符排序
题目
给定一个字符串,仅含英文字母和数字,请按如下规则对其进行排序:
- 排序后,原位置是数字的,排序后仍然是数字;原位置是字母的,排序后仍然是字母。
- 数字:按 0-9 升序。
- 英文字母:大写字母大于小写字母,小写字母按 a-z 升序,大写字母按 A-Z 升序。
时间限制: C/C++ 1000ms, 其他语言:2000ms
内存限制: C/C++ 64MB, 其他语言:128MB
输入
输入为一行字符串,长度范围 [1,1000),字符串中不会出现除英文字母、数字以外的别的字符。
输出
输出排序后的字符串。
样例1
1 | 输入: |
样例2
1 | 输入: |
先将字符串中的数字和字母分别放到两个List里并按要求排序
构建一个新的空字符串res,并遍历inputStr中的每个字符
- 如果是字母,就从排好序的字母列表中取出一个元素放到res末尾
- 如果是数字,就从排好序的数字列表中取出一个元素放到res末尾
1 | private static String characterSort(String inputStr) { |
单板告警统计
题目
假设某系统中有两块单板,这两块单板上产生的告警ID(以十六进制字符串表示)分别存储在列表 arrayA 和列表arrayB 中。
请统计并输出系统中的所有告警ID(即arrayA和arrayB的并集):
- 如果告警ID存在重复,先需去重。
- 然后以告警ID所表示值的升序排序输出
时间限制: C/C++ 1000ms, 其他语言:2000ms
内存限制: C/C++ 256MB, 其他语言:512MB
输入
第一行1个整数,表示告警列表arrayA的长度,取值范围为:[0,1000]
第二行表示告警列表arrayA的数据,告警ID以单空格分隔
第三行1个整数,表示告警列表arrayB的长度,取值范围为:[0,1000]
第四行表示告警列表arrayB的数据,告警ID以单空格分隔
告警ID为无符号整数,以十六进制字符串表示,由数字字符、大写字母A~F组成,固定为 8 个字符。
输出
按升序排序的告警ID,以单空格分隔
样例1
1 | 输入: |
样例2
1 | 输入: |
两个集合取并集,然后把结果放在LIst里升序输出即可
1 | private static String[] getAllFault(String[] arrayA, String[] arrayB) { |