面試 | 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();
}
}
最後



