2019年华为2020届寒假招聘实习生软件类编程题Java篇

第一次写博客

某211大三工科男一枚,准备找软件类的工作,这是博主第一次写博客,不知道是什么流程,内心有一点小小的激动,这篇博客主要是根据华为软件类的机试题,也是我的第一次机试。

第一次机试

昨天晚上七点内心忐忑的打开浏览器,登上页面,因为做过网上的一些题目,知道三条编程题,前面两条应该很水,事实情况也的确如此,但是却未能编译一次通过。第三条当时也没做出来,其实当时已经有了思路,但是时间有点来不及,主要还是自己不够熟练!
下面给出的代码,第一条和第二条都AC了,第三条自己测试了一下,如果第三条有问题,还请大家留言!

第一条

第一条:录入得到一串字符,将字符串中小于1000的最大整数,默认输入为整数
如 输入:123456789 则输出:789
主要的思想就是循环遍历比较大小。
第一条编译了两次,没有考虑到输入的字符串长度小于3的情况。
下面贴上代码

代码

import java.util.Scanner;


public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNextLine()) {
			String num = sc.nextLine();           //读入字符串
			int[] arr = new int[num.length()];    //用来存储每个小于1000的整数
			if(num.length() < 3) {                     //若小于3则直接输出
				System.out.println(num);
			}else {
				for(int i = 0; i < num.length() - 2; i++) {      //遍历将各个小于1000的整数存在数组中
					StringBuffer sb = new StringBuffer();
					sb.append(num.charAt(i));
					sb.append(num.charAt(i+1));
					sb.append(num.charAt(i+2));
					arr[i] = Integer.parseInt(sb.toString());	
				}
				int max = arr[0];
				for(int j = 1; j < arr.length; j++) {        //取出小于1000的最大整数
					if(max < arr[j])
						max = arr[j];
				}
				System.out.println(max);
			}		
		}
	}	   
}

第二条

第二条:录入一串字符和整数,";“分割字符,结尾默认为”;" ,用";“分割字符并编号(从0开始),输入的整数即为编号,最后输出编号的内容,若编号不存在,则输出空。
如 输入:ncx;007ab 0 则输出 ncx
这一条比较简单,不过博主编译了很多次没有通过,一开始怀疑是输出空是不是输出"null”,之后发现原来博主与第一条一样用了while循环,这一条貌似只需要录入一次即可,用while循环会出错,所以无需重复录入。

代码

// An highlighted block
import java.util.Scanner;


public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String str = sc.next() + ";"; 
		int num = sc.nextInt();
		String[] strArr = str.split(";");
		if(num < strArr.length && num >= 0) {
			System.out.println(strArr[num]);
		}else {
			System.out.println("");
		}
	}	   
}

第三条

第三条:
最后一条考试的时候写了一个多小时都没写出来,考试的时候有了大概的思路,
输入2,2 0,0 2,2 3 0,1 2,0 2,1
2,2 代表nm即(2+1)(2+1)的方阵
0,0 代表初始点为(0,0)
2,2 代表初始点为(2,2)
3代表障碍点的个数
(0,1)(2,0 )(2,0)代表障碍点的坐标

在这里插入图片描述
打印出A到B的最短路径 [0 0] [0 1] [1 1] [1 2] [2 2] ,若无法到达则输出No way to destionation(好像是这一串字符= =!)

刚看到这一条的时候,就想到了去年的出差遇大雾城市,心里还有点小激动,不过马上冷静下来,想了想,也很快有了思路,nm的矩阵转换为nm的数组来做,利用Floyd算法输出最短的路径。
理想很丰满,现实很骨感,中间有许多的转换问题,比如说将n*m的矩阵转化为一维数组,路径数组初始化的问题,因为这个题目与出差遇大雾城市不同,可能会出现两个以上的连通域,所以需要对其进行判断。

也可能是我的思路比较复杂,肯定会有更加简单方便的方法,经过这次机试,更加坚定了我找工作的决心!
编写代码时遇到的问题都写在注释上,调试的时候的一些打印函数也被注释,实际并不运行。

代码

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;

/*输入2,2 0,0 2,2 3 0,1 2,0 2,1	           0    1    2
  2 2 代表(2+1)*(2+1)的方阵		       	0  A    X
  0 0 代表初始点为(0,0)				    1  
  2 2 代表初始点为(2,2)				    2  X    X    B
  3代表障碍点的个数					       打印出A到B的最短路径  [0 0] [0 1] [1 1] [1 2] [2 2] 
  0 1 													         0     1     4     5      8
  2 0 
  2 1代表障碍点的坐标
  
*/
public class Main {
	public static void main(String[] args) {
		
		//对输入信息进行操作变成一维数组 以便进行Floyd
		Scanner sc = new Scanner(System.in);
		String str = sc.nextLine();
		String[] strArr = str.split(" ");//正则分割得到各部分信息
		String[] nm =strArr[0].split(",");//得到 n m 行为m+1 列为n+1
		int num = (Integer.parseInt(nm[0]) + 1) * (Integer.parseInt(nm[1]) + 1);// 总格数
		int[][] floyd = new int[num][num];
		int inf = 99999999;
		int[][] path = new int[num][num];
		//初始化 初始化的时候要注意 周围的四个节点不能为-1,即被分割撑了不同的连通域
		for(int i = 0; i < num; i++) {
			for(int j = 0; j < num; j++) {
				path[i][j] = j;
			}
		}
		for(int i = 0; i < Integer.parseInt(strArr[3]); i++) {
			String[] barrier =strArr[4+i].split(",");//得到障碍点横纵坐标
			for(int j = 0; j < num; j++) {
				//floyd障碍点那一行给全部设为inf   path -1横坐标*(m+1) +纵坐标 
				floyd[Integer.parseInt(barrier[0]) * ( Integer.parseInt(nm[1]) + 1) + Integer.parseInt(barrier[1])][j] = inf;
				path[Integer.parseInt(barrier[0]) * ( Integer.parseInt(nm[1]) + 1) + Integer.parseInt(barrier[1])][j] = -1;
				//那一列全部设为inf   
				floyd[j][Integer.parseInt(barrier[0]) * ( Integer.parseInt(nm[1]) + 1) + Integer.parseInt(barrier[1])] = inf;
				path[j][Integer.parseInt(barrier[0]) * ( Integer.parseInt(nm[1]) + 1) + Integer.parseInt(barrier[1])] = -1;
			}
			
		}
		//打印障碍点引入的二维数组 实际程序不使用 inf显示为-1
		/*for (int[] is : floyd) {
			for (int i : is) {
				if(i == inf) {
					System.out.print("-" + 1 + " ");
				}else if(i >= 0) {
					System.out.print("+" + i + " ");
				}else {
					System.out.print(i + " ");
				}
				
			}
			System.out.println("");
		}*/
		
		for(int i = 0; i < num; i++) {
			for(int j = 0; j < num; j++) {
				//如果在这个点的上下左右且值不等于inf则将两个之间的路径设置为1 否则为inf,特别注意不能为第一列-1和最后一列+1
				if((j == i + (Integer.parseInt(nm[1]) + 1) || j == i - (Integer.parseInt(nm[1]) + 1)) 
						&& floyd[i][j] != inf) {
					floyd[i][j] = 1; //如果在这个点的上下左右且值不等于inf则将两个之间的路径设置为1 否则为inf
				}else if((((j == i + 1) && ((i + 1) % (Integer.parseInt(nm[1]) + 1) != 0))
						|| ((j == i - 1) && (i % (Integer.parseInt(nm[1]) + 1) != 0)))
						&& floyd[i][j] != inf){
					floyd[i][j] = 1;
				}else {
					floyd[i][j] = inf;
				}
			}
		}
		for(int i = 0; i < num; i++) {
			floyd[i][i] = 0;
		}
		//打印路径引入的二维数组 实际程序不使用 inf显示为-1
		/*for (int[] is : floyd) {
			for (int i : is) {
				if(i == inf) {
					System.out.print("-" + 1 + " ");
				}else if(i >= 0) {
					System.out.print("+" + i + " ");
				}else {
					System.out.print(i + " ");
				}
				
			}
			System.out.println("");
		}*/
		
		/*     0  1  2  3  4  5  6  7  8
		    0 +0 -1 -1 +1 -1 -1 -1 -1 -1 
			1 -1 +0 -1 -1 -1 -1 -1 -1 -1 
			2 -1 -1 +0 -1 -1 +1 -1 -1 -1 
			3 +1 -1 -1 +0 +1 -1 -1 -1 -1 
			4 -1 -1 -1 +1 +0 +1 -1 -1 -1 
			5 -1 -1 +1 -1 +1 +0 -1 -1 +1 
			6 -1 -1 -1 -1 -1 -1 +0 -1 -1 
			7 -1 -1 -1 -1 -1 -1 -1 +0 -1 
			8 -1 -1 -1 -1 -1 +1 -1 -1 +0 
		 */
		//解决不同连通域中的问题,初始化的问题
		for(int i = 0; i < num; i++) {//起点
			for(int j = 0; j < num; j++) {//终点
				if(floyd[i][j] == inf ) {
			        path[i][j] = -1;
			       }
			}        
		}
			      
		
		for(int k = 0; k < num; k++) {
			for(int i = 0; i < num; i++) {//起点
				for(int j = 0; j < num; j++) {//终点
					if(floyd[i][k] != inf && floyd[k][j] != inf && floyd[i][j] > floyd[i][k] + floyd[k][j]) {
			        	floyd[i][j] = floyd[i][k] + floyd[k][j];
			        	path[i][j] = path[i][k];
			        }
				}        
			}
			      
		}
			  
		
		//打印最短路径
		/*for (int[] is : path) {
			for (int i : is) {
				if(i >= 0) {
					System.out.print("+" + i + " ");
				}else {
					System.out.print(i + " ");
				}
			}
			System.out.println();
		}
		System.out.println();*/
		//打印最短路径长度
		/*for (int[] is : floyd) {
			for (int i : is) {
				if(i == inf) {
					System.out.print("-" + 1 + " ");
				}else if(i >= 0) {
					System.out.print("+" + i + " ");
				}else {
					System.out.print(i + " ");
				}
				
			}
			System.out.println("");
		}*/
		
		//开始结束的位置
		String[] str3 =strArr[1].split(",");
		int start = Integer.parseInt(str3[0]) * (Integer.parseInt(nm[1])+1) + Integer.parseInt(str3[1]);
		//System.out.println(start);
				
		String[] str4 =strArr[2].split(",");
		int end =Integer.parseInt(str4[0]) * (Integer.parseInt(nm[1])+1) + Integer.parseInt(str4[1]);
		//System.out.println(end);
		
		//打印路径
		ArrayList<Integer> getPathNum = new ArrayList<>();
		getPathNum.add(start);
		while(path[start][end] != -1 && start != end) {//等于时也执行所以不用向数组里添加end
			int midPoint = path[start][end];
			getPathNum.add(midPoint);
			start = midPoint;
		}
	
		Iterator<Integer> it = getPathNum.iterator();
		
		while(it.hasNext()) {
			int i = it.next();
			if(it.hasNext() && path[start][end] != -1) {
				System.out.print("[" + i/(Integer.parseInt(nm[1]) + 1) + " " + i%(Integer.parseInt(nm[1]) + 1) + "]");
				System.out.print(" ");
			}else if(start == end) {
				System.out.print("[" + i/(Integer.parseInt(nm[1]) + 1) + " " + i%(Integer.parseInt(nm[1]) + 1) + "]");
			}else {
				System.out.println("No way to destination");
			}
		}
	}
  
}

其实这边在编写代码的时有一个疑惑,就是当最短路径不唯一的时候,应该如何输出。
就差不多这些了,博主赶去准备面试了。

总结

本次机试虽然没有取得一个满意的结果,但我却更加认识到实践的重要性,告诉自己应该不懈努力,大学生不应该颓废,应该有努力的方向。过几天可能就要面试了,希望自己的面试能过吧,太紧张了!!!!!!

猜你喜欢

转载自blog.csdn.net/weixin_44402114/article/details/85933306