华为2020春招笔试(Java岗位)
题目一
我们的系统仅能接受指定格式的命令输入,调皮的小伙伴总是会输入一些系统无法识别的命令引起千奇百怪的结果,请实现一个简单的命令合法性的程序帮助我们进行判断。
系统仅能够接受的命令格式描述如下:
- 单命令,仅支持小写字母,如a,b等
- AND命令,以AND进行的命令拼接,如a AND b
- OR命令,以OR进行的命令拼接,如a OR b
- NOT命令,以NOT为前缀的命令,如NOT a
- 使用AND命令,OR命令,NOT命令拼接起来的命令,如a AND b OR c NOT d
特别注意:
- AND,OR,NOT为系统关键字必须大写
- 系统不接受联系NOT拼接的命令,如NOT NOT a为不合法命令
- 系统不接受使用括号进行的命令拼接,如(a AND b)OR c。
输入描述:
多行判断合法性命令,单行命令长度小于100,不用考虑长度越界的情况。
输出描述:
多行0或1
其中:
0:表示命令不合法
1:表示命令合法
示例1
输入
a AND b
a AND b OR c OR NOT d
输出
1
1
示例2
输入
a AND AND b
A AND b
a and b
输出
0
0
0
思路
题目采用的是控制台输入多行字符串,单词之间是有空格隔开,可以让每一行字符串根据空格符分割填充到字符串数组之中进行操作,根据题目给出的条件可知
- 第一个字符和最后一个字符必定是小写字母
- 相同关键字不能连续
- NOT a前面可以结合其他关键字
代码实现:
import java.util.ArrayList;
import java.util.Scanner;
public class demo1{
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();//保存输出
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()){
String s = sc.nextLine();//读取每一行字符串
if(s.equals("")){
break;
}
String[] str = s.split(" ");//根据空格分隔填充为字符串数组
int len = str.length;
for(int i=0;i<len-1;i++){//这里循环的数组前一个数,最后一个数单独判断
if(str[i].length()==1){
char ch = str[i].charAt(0);
if(!(ch>='a'&&ch<='z')){
//如果单字母不是小写字母直接认定为不合法输入
arrayList.add("0");
break;
}else if(str[i+1].length()==1){
//如果该字母的下一个字符不是关键字,认定拼接不合理,输入不合法
arrayList.add("0");
break;
}
}else if(!(str[i].equals("AND")||str[i].equals("OR")||str[i].equals("NOT"))){
//判断非单字符里面只要不是关键字,都是输入不合法
arrayList.add("0");
}else if(str[i].equals(str[i+1])){
//有连续两个相同字符或关键字出现,认定不合法输入
arrayList.add("0");
break;
}else if((i+1)==str.length-1){
char ch = str[i+1].charAt(0);
if(!(ch>='a'&&ch<='z')){
//如果单字母不是小写字母直接认定为不合法输入
arrayList.add("0");
break;
}else{
//所有条件都满足的情况下才算是合法输入
arrayList.add("1");
break;
}
}
}
}
for(int i=0;i<arrayList.size();i++){
System.out.println(arrayList.get(i));
}
}
}
题目二
题目描述:
小华是社保单位的一位员工,最近小华收到了一项任务,需要统计有多少人来过社保单位,每个人来过几次,小华看着“出入记录薄”想,有没有什么好的办法能让记录更加清晰呢?已知每个人都有唯一的社保号,且社保号固定为10位(前2位数字,第3-5位为大写字母,后5位为数字)。随机输入n个社保号,请输出社保号根据大小排序后的结果(ASCII码小的字符在前),己每个社保号的出入次数。
输入描述:
第1行:n个社保号的个数
第2行:第一个社保号
......
第n+1行:第n个社保号
输出描述:
社保号排序后的结果及社保号出现的次数
一行一个社保号,及出现的次数,社保号与次数之间用空格隔开
输出带回车换行
示例
输入
5
29WTS12345
79EXS43213
30ABD23557
30ABD23446
29WTS12345
输出
29WTS12345 2
30ABD23446 1
30ABD23557 1
79EXS43213 1
思路
这里实际上就是字符串排序+去重+计数,我这里代码就分为3步来走,先进行字符串排序,然后使用hasMap来计数,然后再使用List去重。
代码实现:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
public class test{
public static void main(String []args){
Scanner sc = new Scanner(System.in);
ArrayList<String> list = new ArrayList<>();
HashMap<String,Integer> hashMap = new HashMap<>();
String sNum = sc.nextLine();
int n = Integer.parseInt(sNum);
String []str = new String[n];
for(int i=0;i<n;i++){
str[i] = sc.nextLine();
}
for(int i=0;i<n;i++){
//这里采用选择排序
for(int j=i;j<n;j++){
if(str[i].compareTo(str[j])>=1){
String s = str[i];
str[i] = str[j];
str[j] = s;
}
}
}
for(int i=0;i<n;i++){
//这里用hasMap计数
Integer count= hashMap.get(str[i]);
if(count==null){
count = 1;
}else{
count++;
}
hashMap.put(str[i], count);
}
for(int i=0;i<n;i++){
//这里使用List去重
if(!list.contains(str[i])){
list.add(str[i]);
}
}
for(int i=0;i<list.size();i++){
//按格式输出
System.out.println(list.get(i)+" "+hashMap.get(list.get(i)));
}
}
}
题目三
题目三没有时间做,就记下了题目,其中输出描述还有一个条件没有记起来。
题目描述:
根据输入的头文件列表,判断给定头文件是否存在循环依赖,并输出对应的依赖列表
约束:
- 每个文件依赖的头文件不超过10个,头文件名长度不超过32
- 循环依赖为输入的头文件为起点
- 用例会保证输入的合法性
输入描述:
输入分为两个部分:
1)头文件依赖列表,格式如下:
依赖者:被依赖者1 被依赖者2
2)给定的查找头文件,格式如下:
search head file:需要查找的头文件
输出描述:
1)无循环依赖输出:输出“none loop include *”,其中*号为输入需要查找的头文件
2)有循环依赖输出:“Bad coding -- loop include as bellow:”,然后再输出循环依赖列表
3)子依赖也输出:如两个循环依赖:a.h b.h c.h 及 a.h c.h ,两者都输出
4)没行输出都带一个换行(\r\n)