1. 程式人生 > >2019年華為2020屆寒假招聘實習生軟體類程式設計題Java篇

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");
			}
		}
	}
  
}

其實這邊在編寫程式碼的時有一個疑惑,就是當最短路徑不唯一的時候,應該如何輸出。
就差不多這些了,博主趕去準備面試了。

總結

本次機試雖然沒有取得一個滿意的結果,但我卻更加認識到實踐的重要性,告訴自己應該不懈努力,大學生不應該頹廢,應該有努力的方向。過幾天可能就要面試了,希望自己的面試能過吧,太緊張了!!!!!!