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");
}
}
}
}
其實這邊在編寫程式碼的時有一個疑惑,就是當最短路徑不唯一的時候,應該如何輸出。
就差不多這些了,博主趕去準備面試了。
總結
本次機試雖然沒有取得一個滿意的結果,但我卻更加認識到實踐的重要性,告訴自己應該不懈努力,大學生不應該頹廢,應該有努力的方向。過幾天可能就要面試了,希望自己的面試能過吧,太緊張了!!!!!!