蓝桥杯JAVA-1.入门必知、正常输入输出和快速输入输出

本文最后更新于:January 16, 2022 am

积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里,不积小流无以成江海。齐骥一跃,不能十步,驽马十驾,功不在舍。面对悬崖峭壁,一百年也看不出一条裂缝来,但用斧凿,能进一寸进一寸,能进一尺进一尺,不断积累,飞跃必来,突破随之。

目录

本文主要介绍快速输入输出,正常的输出输出在数据量小的时候还行,大了就拜拜了。推荐使用BufferedReader输入,BufferedWriter输出。因为当输入输出的数据量大于一百万左右就必须使用快速输入输出,不能直接使用Scanner和System.out.print。

1.必知常识

主类名必须是Main,并且交代码时不要加入包名(package),但需要把导入的包加上(import)。如:

1
2
3
4
5
6
7
8
9
10
11
12
// package test; 不要
import java.util.Scanner;
/**
* @Author DragonOne
* @Date 2021/12/5 18:35
* @墨水记忆 www.tothefor.com
*/
public class Main {
public static void main(String[] args) {

}
}

2.输入输出

2.1 正常输入输出

这种是java中非常常见的输入输出方法。

2.1.1 输入

java中的输入与C++中的不一样,不能用cin通吃(不知道的也没关系)。倒是和C中的有一点类似。

  1. 首先定义一个可以在控制台从键盘接受数据的Scanner对象,需要导入包:import java.util.Scanner;。如下:
1
2
3
4
5
6
7
8
9
10
11
12
import java.util.Scanner;

/**
* @Author DragonOne
* @Date 2021/12/5 18:35
* @墨水记忆 www.tothefor.com
*/
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
}
}

这样,就可以用cin对象配合.nextXXXX()方法接受数据了。XXXX表示不同类型的数据。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int nu = cin.nextInt(); //int类型
System.out.println(nu);
float fl = cin.nextFloat(); //float类型
System.out.println(fl);
double dou = cin.nextDouble(); //double类型
System.out.println(dou);
String str = cin.next(); //String类型,遇到空格结束
System.out.println(str);
String st = cin.nextLine(); //String类型,读取一行数据,遇到换行结束。类似gets
cin.close();
}
}
  1. 多组数据输入。使用cin.hasNext。返回值是bool值,作用是当在缓冲区内扫描到字符时,会返回true, 否则会发生阻塞,等待数据输入。

使用 while + cin.hasNext() 相当于 while(scanf())。和cin.nextXXX()方法类似,cin.hasNextXXX()也有针对不同类型变量的方法。如下:

cin.hasNext():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
float a,b;
int c;
while(cin.hasNext()){
a = cin.nextFloat();
b = cin.nextFloat();
c= cin.nextInt();
System.out.println(a+" "+b+" "+c);
}
cin.close();
}
}

2.1.2 输出

java中往控制台输出的几种常用函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
String s = "asdf";
int a = 123;
System.out.println("234"); //输出并换行
System.out.print(165); //输出不换行
System.out.printf("%d %s",a,s); //输出不换行
cin.close();
}
}

//输出
234
165123 asdf

2.2 快速输入输出

2.2.1 输出

输出比较简单,先说。

BufferedWriter输出

BufferedWriter。主要使用 BufferedWriter类中的 write() 类进行输出。会抛出异常。 当数据量大的时候一定要使用这个类进行输出。输出后并不会自动换行。

需要注意的是 write() 不能直接输出int类型, 因为write(int a) 会输出其对应的ASCii码的字符 ,比如输出 65 会显示 A。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Main {
public static void main(String[] args) throws Exception {
Scanner cin = new Scanner(System.in);
BufferedWriter cout = new BufferedWriter(new OutputStreamWriter(System.out));
int a1 = 66;
char a2 = '6';
String a3 = "66";
cout.write(a1);
cout.write("\n");
cout.write(a2);
cout.write("\n");
cout.write(a3);
cout.write("\n");
cout.flush();
cin.close();
}
}

//输出
B
6
66

所以当需要输出一个int类型的变量时, 可以用Integer.toString(int a)方法 将其变为字符串形式输出。或者使用 + 拼接一个字符串,这样 参数整体就是一个字符串了,比如加一个换行符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {
public static void main(String[] args) throws Exception {
Scanner cin = new Scanner(System.in);
BufferedWriter cout = new BufferedWriter(new OutputStreamWriter(System.out));
int a1 = 66;
cout.write(a1+"\n");
cout.write(Integer.toString(a1));
cout.flush();
cin.close();
}
}

//输出
66
66

BufferedWriter常用方法:

方法 描述
void write(int c) 输出整数对应的ASCII码字符
void write(String s,int off,int len) 输出在字符串s中,从下标为off开始,长度为len的子串
void write(char[] cbuf,int off,int len) 类似同上描述。
void write(char[] cbuf) 输出字符数组中的全部字符
void write(String str) 输出字符串
PrintWriter输出
1
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

可以看出来,其实和BufferedWriter的定义声明差不多,所以,可以参考BufferedWriter的用法。不同的是,PrintWriter还可以用println输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//所需包
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

// 输出分为两步:
// 1、先通过print()或println()方法把需要输出的内容放入缓冲区,
// 2、然后通过flush()将缓冲区的内容输出到控制台
public static void main(String[] args) {
/* 下面这是IO流包装,直接套用就好*/
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
out.println("Greater than");/*输出内容*/
out.println("Less than");
out.println("Equal");
out.flush();/*刷新输出缓冲区,把缓冲区的内容输出到控制台。可以自行尝试把这句代码写上和注释掉查看效果。*/
}

2.2.2 输入

BufferedReader输入
1
BufferedReader cin = new BufferedReader(new InputStreamReader(System.in));

常用方法:

方法 描述
int read() 读取单个字符.可读入空格回车
int read(char[] cbuf,int off,int len) 将字符读入数组的指定位置
int read(char[] cbuf) 读入字符数组
String readLine() 读入一行数据.可读入空格

需要注意的是 在windows中按一下回车键 一共有两个字符 “\n\r” 而read()只能读取一个字符,所以如要要用read来达到吸收回车的目的,需要用两个read(); 如果用readLine()的话会将”\n\r”全部吸收 , 所以只需要一个readLine()来吸收回车。

以下是在Mac环境下,所以没有回车,只有换行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

public class Main {
public static void main(String[] args) throws Exception {
BufferedReader cin = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter cout = new BufferedWriter(new OutputStreamWriter(System.out));
int b = cin.read(); // read()只读取一个字符
int c = cin.read(); // 吸收 \n
int x = cin.read();
String d = cin.readLine();
cout.write("\n");
cout.write(b + "\n");
cout.write(c + "\n");
cout.write(x + "\n");
cout.write(d + "\n");
cout.flush();
}
}

//输入
1
ABC DEF

//输出
49
10
65
BC DEF

StreamTokenizer输入

StreamTokenizer只能接收数字或字母,如果输入除空格和回车以外的字符(如:!@#$%^&*()[]{})无法识别,会显示null。

StreamTokenizer可以获取输入流并根据空格和回车分割成Token(标记),用nextToken方法读取下一个标记 。

如果标记是字符串,用st.sval获取标记,如果是数字用st.nval获取标记,st.navl是double类型。

  1. 输入数字(nval)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//所需包
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
//简写为
import java.io.*;


public static void main(String[] args) throws Exception {
/* 下面这是IO流包装,可以看不懂,直接套用就好*/
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();/*nextToken()方法相当于让光标指向下一个位置*/
int n = (int) in.nval;//获取整数;
out.println(n);
out.flush();/*刷新输出缓冲区并输出*/
}
  1. 输入字符串(sval)
1
2
3
4
5
6
7
8
9
public static void main(String[] args) throws Exception {
/* 下面这是IO流包装,可以看不懂,直接套用就好*/
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();/*nextToken()方法相当于让光标指向下一个位置*/
String str = in.sval;/*注意:sval是获取不带空格的字符串,含有空格的字符串无法全部读取,只会获取空格之前的。并且只能用来获取含字母和数字、中英文句号的字符串。具体情况需要自行尝试,至少写者在测试时是这样的。因为网上有些说的是只能是字母串,不能含数字或其他,否则会返回null。*/
out.println(str);
out.flush();/*刷新输出缓冲区并输出*/
}
  1. 多组输入
1
while (in.nextToken() != StreamTokenizer.TT_EOF) //StreamTokenizer.TT_EOF这个是个参数,就是相当于EOF了。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) throws Exception {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

while (in.nextToken() != StreamTokenizer.TT_EOF){
int n = (int) in.nval;
in.nextToken();
int m = (int) in.nval;
out.println(n+" "+m);
out.flush();
}
}

总结

以上仅仅代表个人意见,具体情况,根据实际情况而定。

对于输入和输出,不同的类型用不同的输入。

输入

读数字:StreamTokenizer(字符串也可以)。但是需要注意的是,不能用来读取纯数字字符串。但也有解决办法。原因点击可见

读字符(串):BufferedReader

两种非必要最好不要混用。

输出

反正自己觉得PrintWriter是比较方便的。根据自己而定。

提供一个自己的模板。

1
2
3
4
5
public static BufferedReader cin = new BufferedReader(new InputStreamReader(System.in));
public static BufferedWriter cout = new BufferedWriter(new OutputStreamWriter(System.out));

public static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

基本模板

我自己的基本模板。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import java.io.*;


/**
* @Author DragonOne
* @Date 2021/12/5 21:27
* @墨水记忆 www.tothefor.com
*/
public class Main {
public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
public static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));

public static void main(String[] args) throws Exception {
int n = nextInt();
long m = nextLong();
double d = nextDouble();
cout.println(n);
cout.flush();
cout.println(m);
cout.flush();
cout.println(d);
cout.flush();

closeAll();
}
public static void cinInit(){
cin.wordChars('a', 'z');
cin.wordChars('A', 'Z');
cin.wordChars(128 + 32, 255);
cin.whitespaceChars(0, ' ');
cin.commentChar('/');
cin.quoteChar('"');
cin.quoteChar('\'');
cin.parseNumbers(); //还原默认数字
}

public static int nextInt() throws Exception{
cin.nextToken();
return (int) cin.nval;
}
public static long nextLong() throws Exception{
cin.nextToken();
return (long) cin.nval;
}
public static double nextDouble() throws Exception{
cin.nextToken();
return cin.nval;
}
public static String nextString() throws Exception{
cin.nextToken();
return cin.sval;
}
public static void closeAll() throws Exception {
cout.close();
in.close();
out.close();
}

}