面試 | Java 演算法的 ACM 模式


前言

經常在 LeetCode 上用核心程式碼模式刷題的小夥伴突然用 ACM 模式可能會適應不過來,把時間花在輸入輸出上很浪費時間,因此本篇筆記對 Java 演算法的 ACM 模式做了個小總結;

除此之外,需要注意一些小細節:

  • 1. 數字讀取到字元串讀取間需要用 in.nextLine() 換行;

1. 數字處理

  • 如果是讀取 Long,則使用:in.hasNextLong()Long a = in.nextLong()
  • 讀取小數:f = scan.nextFloat()double weight = scan.nextDouble()

1.1 多組空格分隔的兩個正整數

輸入包括兩個正整數a,b(1 <= a, b <= 10^9),輸入數據包括多組;

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) { // 注意 while 處理多個 case
            int a = in.nextInt();
            int b = in.nextInt();
            //處理
        }
    }
}

1.2 第一行組數接空格分隔的兩個正整數

第一行輸入數據個數,後面輸入數據;

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        for(int i = 0; i < num; i++) { // 注意 while 處理多個 case
            int a = in.nextInt();
            int b = in.nextInt();
            //處理
        }
    }
}

1.3 空格分隔的兩個正整數為0 0 結束

輸入包括兩個正整數a,b(1 <= a, b <= 10^9), 如果輸入為0 0則結束輸入;

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) { // 注意 while 處理多個 case
            int a = in.nextInt();
            int b = in.nextInt();
            if(a ==0 && b == 0) break;
            //處理
        }
    }
}

1.4 每行第一個為個數後帶空格分割整數為0結束

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) { // 注意 while 處理多個 case
            int n = in.nextInt();
            if(n == 0) break;
            int sum = 0;
            for (int i = 0; i < n; i++) {
                sum += in.nextInt();
            }
            System.out.println(sum);
        }
    }
}

2. 字元串處理

比較項 next( ) nextLine( )
說明 只能讀取到空格之前的字元串 可以讀取空格的字元串
比如「你好 java」 「你好」 「你好 java」
使用前判斷 in.hasNext() in.hasNextLine()

2.1 第一行個數第二行字元串

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        in.nextLine();
        while (in.hasNext()) { // 注意 while 處理多個 case
            String[] s = in.nextLine().split(" ");
            //處理
        }
    }
}

2.2 多行空格分開的字元串

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) { // 注意 while 處理多個 case
            String[] s = in.nextLine().split(" ");
            //處理
        }
    }
}

3. 輸出格式化相關

  • 輸出有兩種方式:String str=String.format(示例)System.out.printf(示例)
  • 向上取整用:Math.ceil(1.01),向下取整用:Math.floor(1.01)

3.1 轉換符

轉換符 說明 示例 輸出
%s 字元串 “Hi,%s:%s.%s”, “王南”,”王力”,”王張” Hi,王南:王力.王張
%c 字元 “字母a的大寫是:%c %n”, ‘A’ 字母a的大寫是:A
%b 布爾 “3>7的結果是:%b %n”, 3>7 3>7的結果是:false
%d 整數(十進位) “100的一半是:%d %n”, 100/2 100的一半是:50
%x 整數(十六進位) “100的16進位數是:%x %n”, 100 100的16進位數是:64
%o 整數(八進位) “100的8進位數是:%o %n”, 100 100的8進位數是:144
%f 浮點 “50元的書打8.5折扣是:%f 元%n”, 50*0.85 50元的書打8.5折扣是:42.500000 元
%a 浮點(十六進位) “上麵價格的16進位數是:%a %n”, 50*0.85 上麵價格的16進位數是:0x1.54p5
%e 指數 “上麵價格的指數表示:%e %n”, 50*0.85 上麵價格的指數表示:4.250000e+01
%g 通用浮點(f和e類型中較短的) “上麵價格的指數和浮點數結果的長度較短的是:%g %n”, 50*0.85 上麵價格的指數和浮點數結果的長度較短的是:42.5000
%h 散列碼 “字母A的散列碼是:%h %n”, ‘A’ 字母A的散列碼是:41
%% 百分比 “上面的折扣是%d%% %n”, 85 上面的折扣是85%
%n 換行符
%tx 日期與時間

3.2 搭配轉換符的標誌

標誌 說明 示例 輸出
. 後接保留多少位小數(四捨五入) (“%.2f”,3.555) 3.56
+ 為正數或者負數添加符號 (“%+d”,15) +15
左對齊 (“%-5d”,15) |15 |
0 數字前面補0 (“%04d”, 99) 0099
空格 在整數之前添加指定數量的空格 (“% 4d”, 99) | 99|
, 以「,」對數字分組 (“%,f”, 9999.99) 9,999.990000
( 使用括弧包含負數 (“%(f”, -99.99) (99.990000)
# 如果是浮點數則包含小數點,如果是16進位或8進位則添加0x或0 (“%#x”, 99) (“%#o”, 99) 0x63 0143
< 格式化前一個轉換符所描述的參數 (“%f和<3.2f”, 99.45) 99.450000和99.45
$ 被格式化的參數索引 (“%1$d,%2$s”, 99,”abc”) 99,abc

4. ACM 模式模板

public class Main {

    public static void main(String[] args) {
        //1.數據輸入
        Scanner in = new Scanner(System.in);
        //讀數字
        int numLen = in.nextInt();
        int[] numArr = new int[numLen];
        int i = 0;
        while(in.hasNextInt() && i < numLen){
            numArr[i] = in.nextInt();
            i++;
        }
        //讀字元串
        int strLen = in.nextInt();
        in.nextLine(); //數字到字元串要換行
        String[] strArr = new String[strLen];
        //或者 strArr[] = in.nextLine().split(" ");
        int j = 0;
        while(in.hasNextLine() && j < strLen){
            strArr[j] = in.nextLine();
            j++;
        }
        
        //2. 處理
        Solution solution = new Solution();
        String result = solution.process(numArr, strArr);
        
        //3. 輸出
        System.out.println(result);
        //四捨五入輸出小數
        String str = String.format("%.2f",3.555);
        System.out.println(str);
    }
}

//下面類似 LeetCode 的核心程式碼模式
class Solution {
    public String process(int[] nums, String[] strs) {
        StringBuilder sb = new StringBuilder();
        sb.append(Arrays.toString(nums));
        sb.append(" && ");
        sb.append(Arrays.toString(strs));
        return sb.toString();
    }
}

最後

新人製作,如有錯誤,歡迎指出,感激不盡!
歡迎關注公眾號,會分享一些更日常的東西!
如需轉載,請標註出處!