大部分的算法题都需要进行控制台的输入输出
读入
Scanner类
一般都是使用 Scanner类 读入控制台数据
//Scanner类 在 java.util 包中,所以需要import
import java.util.Scanner;//import java.util.*;也行
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
String str = in.next(); //读入一个字符串,以空格为分界
int a = in.nextInt(); //读入int类型
double d = in.nextDouble(); //读入double类型
long l = in.nextLong(); //读入long类型
boolean bool = in.nextBoolean(); //读入boolean类型
String line = in.nextLine(); //如入一行字符串,以回车(\n)为分界
//没有nextChar(),可以用charAt(0)来转换
char ch = in.next().charAt(0);
//好像关不关都没影响
in.close();
}
}
Scanner读取数据方便,但速度较慢,所以有了更快速的方案
BufferedReader类
使用 BufferedReader类 更快的读入
//BufferedReader类 在 java.io 包中
import java.io.*;
public class Main{
//BufferedReader类要处理异常,throws或try catch均可
public static void main(String[] args) throws Exception{
//创建一个BufferedReader对象
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int i = in.read();//读入一个字符,返回的是int值(ASCII码)
String str = in.readLine();//读入一行数据
//记得关闭流
in.close();
}
}
BufferedReader类 的读入不同于 Scanner类 ,read方法是读取一个字符,返回该字符的ASCII码。
例如,读取“abc”,会返回 97(a的ASCII码),读入 12 ,会返回 49(1 的ASCII码)。
所以,read方法并不好使。选择使用readLine方法来读取。
readLine方法
//读取字符串,如: abc
String str = in.readLine();
//读入int值,如:12
int a = Integer.parseInt(in.readLine());//使用Integer.parseInt()String转换为int
//读入单行内的多个字符串,如:ab ac ad bc bd
String[] ss = in.readLine().trim().split(" ");
//trim方法的作用去除可能存在的首尾空格
//split方法用于分割字符串,参数(" ")表示将字符串以空格为分隔符分割
//读入少量int值,如:12 13 14
int a,b,c;
String[] ss = in.readLine().trim().split(" ");
a = Integer.parseInt(ss[0]);
b = Integer.parseInt(ss[1]);
c = Integer.parseInt(ss[2]);
很明显,如果使用读入少量int值得方式不适用于读入大量数据,所以,需要一个将String数组转换为int数组的方法。
String[] 转 int[]
常规方式就是for循环了
//需要读入 1 2 3 4 5 6 7 8
String[] ss = in.readLine().trim().split(" ");
int[] a = new int[ss.length()];
for(int i = 0 ; i < ss.length() ; i++) a[i] = Integer.parseInt(ss[i]);
//或foreach循环
int cnt = 0;
for(String str : ss) a[cnt++] = Integer.parseInt(str);
有常规的就有不常规的。
String[] ss = in.readLine().trim().split(" ");
//使用java8的stream
int[] a = Arrays.stream(ss).mapToInt(Integer::parseInt).toArray();//Arrays需要导入java.util.Arrays
//可以省去中间变量ss。
int[] a = Arrays.stream(in.readLine().trim().split(" ")).mapToInt(Integer::parseInt).toArray();
速度对比
并没有进行数据测试,就用我做的一道题来看了。。
快速排序
给定你一个长度为n的整数数列。
请你使用快速排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在1~109109范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1 ≤ n ≤ 100000
输入样例:
5 3 1 2 4 5
输出样例:
1 2 3 4 5
数据量 105
代码:
使用Scanner类
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int[] a = new int[n];
for(int i = 0 ; i < n ; i++) a[i] = scan.nextInt();
qs(a,0,n-1);
for(int i : a) System.out.print(i+" ");
}
public static void qs(int[] a , int l , int r){
if(l >= r) return;
int x = a[l] , i = l - 1 , j = r + 1;
while(i < j){
do{i++;} while(a[i] < x);
do{j--;} while(a[j] > x);
if(i < j){
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
qs(a,l,j);
qs(a,j+1,r);
}
}
使用BufferedReader类
import java.util.*;
import java.io.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(in.readLine().trim());
int[] a = Arrays.stream(in.readLine().trim().split(" ")).mapToInt(Integer::parseInt).toArray();
qs(a,0,n-1);
for(int i : a) System.out.print(i+" ");
in.close();
}
public static void qs(int[] a , int l , int r){...}//同上,省略
}
运行时间:
上面的是BufferedReader,下面的是Scanner
很明显的提升了速度。
觉得不够快?那是还没优化输出速度。
输出
System.out
学java的应该没有不会的吧。
System.out.println(...); //输出并换行
System.out.print(..); //输出后不换行
比较特殊的是printf
//C语言printf的仿制,用于格式化输出
System.out.printf(占位字符串,输出值);
/*常用的格式字符
%d 整数
%s 字符串
%f 浮点数
*/
//输出12
System.out.printf("%d",12);
//用于指定小数位数的值
System.out.printf("%.2f",123.333);//.2表示输出小数点后两位,如果不够2位会补上0
PrintWriter类
System.out 不够快,使用PrintWriter
//PrintWriter属于java.io包
import java.io.*;
public class Main{
public static void main(String[] args){
PrintWriter out = new PrintWriter(System.out);
//使用跟System.out一样
out.print();
out.println();
//记得关闭流
out.close();
}
}
将 快速排序 题目在 Bufferde的基础上使用 PrintWriter 类
代码:
import java.util.*;
import java.io.*;
public class Main{
static int N = 100000;
public static void main(String[] args) throws Exception{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
int n = Integer.parseInt(in.readLine().trim());
int[] a = Arrays.stream(in.readLine().trim().split(" ")).mapToInt(Integer::parseInt).toArray();
qs(a,0,n-1);
for(int i : a) out.print(i+" ");
in.close();
out.close();
}
public static void qs(int[] a , int l , int r){...}//同上,省略
}
运行时间:
最上面的使用 PrintWriter类。
可以看到,又提升了速度。
总结
BufferedReader 和 PrintWriter 都能提升速度,但代码相比 Scanner 和 System.out 要多。
以 码字时间 换 运行时间,需要看题目的数据量来取舍了。