ACM pattern
- 注意类名必须为 Main, 不要有任何 package xxx 信息
1.输入与输出
1. 单个输入与单行输入
输入一个数,或者字符串,或者一行数中间用空格隔开:
1.1输入一个数
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
System.out.println(num);
}
}
byte/ double/ float/ int/ long/ short 类型的类似:
nextDouble();
nextByte();
nextLong();
nextBoolean();
1.2输入一个字符串
next()、nextLine()都可以:
不过要注意
next()不会吸取字符前后的空格/Tab键,只吸取字符,开始吸取字符(字符前后不算)直到遇到空格/Tab键/回车截止吸取;
nextLine()吸取字符前后的空格/Tab键,回车键截止。
String str1 = sc.next(); //接收第1个值
String str2 = sc.nextLine(); //接收的是一整行
1.3输入一个char类型字符
Scanner本身并不支持获取char类型的数据,但是可以通过charAt()方法截取string的首位来获取char类型的数据。
char c = scanner.next().charAt(0);
输入一行数据or字符串,中间用空格隔开
对于不同数据类型的方法都类似,连续用几次next()或者nextInt()函数:
String a = sc.next();// 接收第1个值
String b = sc.next();// 接收第2个值
String c = sc.next();// 接收第3个值
2.多行输入
2.1给出了矩阵的行列数,用for遍历
第一行是两个用空格隔开的正整数n与m,n为行数,m为列数。
接下来的n行,每行是m个用空格隔开的正整数。如:
2 3
5 6 8
1 6 9
想要用二维数组接收:
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//用二维数组接收:
int m = in.nextInt();
int n = in.nextInt();
int[][] nums = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
nums[i][j] = in.nextInt();
System.out.print(nums[i][j]);
}
}
}
}
注意在验证的时候,分隔号一定要用双引号隔开,单引号字符会参与计算!!
2.2没有给出具体的行列数,用hasNextLine()判断
有些输入可能是:
输入一个矩阵,每行以空格分隔。
1 2 3
56 8 2 9
对于这种没有给定矩阵行列数的输入,我们只能按照字符串拆分来进行。
Integer.parseInt(s)的作用就是把字符串s解析成有符号的int基本类型。
String s1 = "1000";
String s2 = "1000";
int n1 = Integer.parseInt(s1);
int n2 = Integer.parseInt(s2);
if (n1 == n2) { System.out.println("Integer.parseInt(s1) == Integer.parseInt(s2)");
}
Integer.valueOf(s)把字符串s解析成Integer对象类型,返回的integer 可以调用对象中的方法。
String s = "123";
Integer integer = Integer.valueOf(s);
System.out.println("integer : " + integer);
联系:
这里提一下parseInt()
与valueOf()
的区别:
Integer.parseInt(str)
返回值是int型的;
Integer.valueOf(str)
返回值是Integer型的。
但是
Integer.parseInt(s)是把字符串解析成int基本类型,Integer.valueOf(s)是把字符串解析成Integer对象类型,其实int就是Integer解包装,Integer就是int的包装,在jdk8中已经自动实现了自动解包装和自动包装,所以两种方式都能得到想要的整数值。
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
List<List<Integer>> list = new ArrayList<>();
while (in.hasNextLine()) {
List<Integer> line = new ArrayList<>();
String str = in.nextLine();
String[] arr = str.split(" ");
for (String s : arr) {
line.add(Integer.valueOf(s));
}
list.add(line);
}
System.out.println(list);
}
}
2.3输入数组中带有中括号和逗号
有些输入可能是,输入一个矩阵:
[[3,2,3],
[1,6,5],
[7,8,9]]
对于这种没有给定矩阵行列数的输入,而且还包含中括号和逗号的输入,我们也是只能按照字符串拆分来进行。这里逗号和右中括号是关键。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
List<List<Integer>> list = new ArrayList<>();
while (in.hasNextLine()) {
List<Integer> line = new ArrayList<>();
String str = in.nextLine();
//只要改这里就可以,加几个replace()
//string.replace(char oldChar, char newChar)
//replace()方法用 新的字符/文本 替换字符串中每个匹配的旧字符/文本。
String[] arr = str
.replace("[", "")
.replace("]", "")
.replace("],", "")
.replace(" ", "")
.split(",");
for (String s : arr){
line.add(Integer.valueOf(s));
}
list.add(line);
}
System.out.println(list);
}
}
3.解析逗号分隔符的字符串
输入用逗号分隔的字符串: 1,5,9,6,5,7,2
想要接收后变成int类型数组:
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.next();
String[] arr = str.split(",");
int[] nums = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
nums[i] = Integer.parseInt(arr[i]);
System.out.print(nums[i]);
}
}
}
4.输出写法
//换行打印,输出之后会自动换行
System.out.println();
//不换行打印
System.out.print();
//按格式输出
System.out.printf();
对于printf
:
/*** 输出字符串 ***/
// %s表示输出字符串,也就是将后面的字符串替换模式中的%s
System.out.printf("%s", new Integer(1212));
// %n表示换行
System.out.printf("%s%n", "end line");
// 还可以支持多个参数
System.out.printf("%s = %s%n", "Name", "Zhangsan");
// %S将字符串以大写形式输出
System.out.printf("%S = %s%n", "Name", "Zhangsan");
/*** 输出整数类型***/
Integer iObj = 342;
// %d表示将整数格式化为10进制整数
System.out.printf("%d; %d; %d%n", -500, 2343L, iObj);
// %o表示将整数格式化为8进制整数
System.out.printf("%o; %o; %o%n", -500, 2343L, iObj);
// %x表示将整数格式化为16进制整数
System.out.printf("%x; %x; %x%n", -500, 2343L, iObj);
// %X表示将整数格式化为16进制整数,并且字母变成大写形式
System.out.printf("%X; %X; %X%n", -500, 2343L, iObj);
/*** 输出浮点类型***/
Double dObj = 45.6d;
// %f表示以十进制格式化输出浮点数
System.out.printf("%f; %f; %f%n", -756.403f, 7464.232641d, dObj);
// 还可以限制小数点后的位数
System.out.printf("%.1f; %.3f; %f%n", -756.403f, 7464.232641d, dObj);
5.注意点
- 多组测试数据:
如果出现多组测试数据放在一起的情况,直接在最外层套while(sc.hasNext()),每组测试数据进入一次while循环,运行一次主函数。一直等待输入,除非终止程序。
- 高精度:
BigInteger和BigDecimal可以说是acmer选择java的首要原因。
函数:add, subtract, divide, mod, compareTo等,其中加减乘除模都要求是BigInteger(BigDecimal)和BigInteger(BigDecimal)之间的运算,所以需要把int(double)类型转换为BigInteger(BigDecimal),用函数BigInteger.valueOf()。
- 一个非常容易出错的地方:(nextInt转nextLine接收)
假设输入为:
3
a 10 1 2
b 10 2
c 10 3
第一行是是数字n,表示下面有n行输入,下面的n行有字母,也有数字,字母只是标识符,不参与运算,数字的个数不固定,每一行的数字需要用List存储下来,最后将每一行的List放入一个大的List中。
正确代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
//需要在后面添加sc.nextLine();换到下一行
sc.nextLine();
List<List<Integer>> adj = new ArrayList<>();
for (int i = 0; i < n; i++) {
List<Integer> list = new ArrayList<>();
String[] inputs = sc.nextLine().split(" ");
for (int j = 1; j < inputs.length; j++) {
list.add(Integer.valueOf(inputs[j]));
}
adj.add(list);
System.out.println(list);
}
}
}
-
赛码平台注意点:
-
不要自定义包名称,否则会报错,即不要添加package answer之类的语句;
-
写很多个类,但是必须有一个类名为Main,并且为public属性,并且Main为唯一的public class;
-
Main类的里面必须包含一个名字为’main’的静态方法(函数),这个方法是程序的入口。
-
2.数字处理
- 如果是读取 Long,则使用:
in.hasNextLong()
和Long a = in.nextLong()
; - 读取小数:
f = scan.nextFloat()
或double weight = scan.nextDouble()
;
1.1多组空格分隔的两个正整数-每组个数相同
(1)输入描述:
输入包括两个正整数a,b(1 <= a, b <= 1000),输入数据包括多组。
(2)输出描述:
输出a+b的结果
(3)示例
输入:
1 5
10 20
输出:
6
30
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//注意while 处理多个case
while (in.hasNext()) {
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a + b);
}
}
}
1.2第一行组数接空格分隔的两个正整数-每组个数相同
(1)输入描述:
输入第一行包括一个数据组数t(1 <= t <= 100)
接下来每行包括两个正整数a,b(1 <= a, b <= 1000)
(2)输出描述:
输出a+b的结果
(3)示例
输入:
2
1 5
10 20
输出:
6
30
代码:
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++) {
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a+b);
}
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
//num从最高到0的循环
while (num--> 0) {
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a+b);
}
}
}
1.3空格分隔的两个正整数为 0 0 结束
(1)输入描述:
输入包括两个正整数a,b(1 <= a, b <= 10^9),输入数据有多组, 如果输入为0 0则结束输入
(2)输出描述:
输出a+b的结果
(3)示例
输入:
1 5
10 20
0 0
输出:
6
30
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
List<Integer> list = new ArrayList<Integer>();
Boolean endFlag = false;
// 注意 while 处理多个 case
// 注意 hasNext 和hasNextLine 区别
while (in.hasNextInt() && !endFlag) {
int a = in.nextInt();
int b = in.nextInt();
if(a == 0 && b == 0) {
endFlag = true;
} else {
list.add(a+b);
}
list.forEach(e -> System.out.println(e));
}
}
}
1.4多组空格分隔的两个正整数-每组个数不同
(1)输入描述:
输入数据有多组, 每行表示一组输入数据。
每行的第一个整数为整数的个数n(1 <= n <= 100)。
接下来n个正整数, 即需要求和的每个正整数。
(2)输出描述:
每组数据输出求和的结果
(3)示例
输入:
4 1 2 3 4
5 1 2 3 4 5
输出:
14
20
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//注意while 处理多个case
while (in.hasNext()) {
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a + b);
}
}
}
1.5每行第一个为个数后带空格分割整数为0结束
(1)输入描述:
输入数据包括多组。
每组数据一行,每行的第一个整数为整数的个数n(1 <= n <= 100), n为0的时候结束输入。
接下来n个正整数,即需要求和的每个正整数。
(2)输出描述:
每组数据输出求和的结果
(3)示例
输入:
4 1 2 3 4
5 1 2 3 4 5
0
输出:
14
20
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
Boolean endFlag = false;
while (in.hasNextInt() && !endFlag) {
int a = in.nextInt();
if(a != 0) {
int sum = 0;
for (int i = 0; i < a; i++) {
sum += in.nextInt();
}
list.add(sum);
}else {
endFlag = true;
}
}
list.forEach(e -> System.out.println(e));
}
}
1.6第一行组数接空格分隔的两个正整数-每组个数不同
(1)输入描述:
输入数据包括多组。
每组数据一行,每行的第一个整数为整数的个数n(1 <= n <= 100), n为0的时候结束输入。
接下来n个正整数,即需要求和的每个正整数。
(2)输出描述:
每组数据输出求和的结果
(3)示例
输入:
2
4 1 2 3 4
5 1 2 3 4 5
输出:
14
20
代码:
import java.util.*;
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++) {
int len = in.nextInt();
int res = 0;
for (int j = 0; j < len; j++) {
int a = in.nextInt();
res += a;
}
System.out.println(res);
}
}
}
1.7 输入一个数组,且给出了数组的长度
输入:
7
1 2 3 4 5 6 7
输出:
1 2 3 4 5 6 7
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int len = in.nextInt();
int[] array = new int[len];
for (int i = 0; i < len; i++) {
array[i] = in.nextInt();
}
System.out.println(Arrays.toString(array));
}
}
2.字符串处理
比较项 | next( ) | nextLine( ) |
---|---|---|
说明 | 只能读取到空格之前的字符串 | 可以读取空格的字符串 |
比如“你好 java” | “你好” | “你好 java” |
使用前判断 | in.hasNext() | in.hasNextLine() |
2.1 第一行个数第二行字符串
输入:
2
a b c
1 2 3
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
in.nextLine();
while (in.hasNext()){
String[] s = in.nextLine().split(" ");
System.out.println(s);
}
}
}
2.2多行空格分开的字符串
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextLine()){
String[] s = in.nextLine().split(" ");
System.out.println(s);
}
}
}
3.核心模板
import java.util.*;
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();
}
}