刷题过程中遇到的一些知识点
输入
Scanner in = new Scanner(System.in);
int num=in.nextInt();//接收数字,以空格或回车分割
in.nextLine();//nextInt()等与nextline()一起使用必须过滤回车
String str=in.nextLine();//接收一整行,包括空格
//读取一行文本,当遇到'\n'和'\r'结束
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
String s=bf.readLine();
第二种方法比第一种快,适合输入数据很长时使用
输出
多个结果中间用空格连接,结尾无空格
List<String> ls=List.of("a","b","c");
System.out.println(String.join(" ", ls));
for (int i=0;i<n;i++) {
for (int j=0;j<m-1;j++) {
System.out.format("%d ", mat[i][j]);
}
System.out.format("%d\n", mat[i][m-1]);
}
集合
Set
初始化
方法一
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Integer> s = new HashSet<>();
s.add(1);
s.add(2);
}
}
方法二
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Integer> s = new HashSet<>(Arrays.asList(1,2));
}
}
类型转换
String转为char
//String.charAt(index)
//得到String中某一位置的char
String s="Hi!";
char c=s.charAt(2);
System.out.println(c);
//String.toCharArray()
//得到包含整个String的char数组
//这样可以通过索引访问String中任意位置的元素
char[] chars=s.toCharArray();
System.out.println(chars);
System.out.println(chars[2]);
char转为String
String s=String.valueOf('a');//效率最高
String s=String.valueOf(new char[] {'H','i','!'});
String s=Character.toString('b');
String s=new Character('c').toString();
String s=""+'d';//虽然简单,但是效率最低
String s=new String(new char[] {'e'});
String转为int
String s="123";
int x=Integer.valueOf(s);
System.out.println(x);
int转为String
int x=123;
String s=String.valueOf(x);
System.out.println(s);
List转为Array
List<Integer> list = List.of(12, 34, 56);
Integer[] array = list.toArray(new Integer[3]);
for (Integer n : array) {
System.out.println(n);
}
Array转为List
Integer[] array = { 1, 2, 3 };
List<Integer> list = List.of(array);
字符转为Ascii码
char c='a';
int x=(int) c;
System.out.println(x);
Ascii码转为字符
int x=97;
char c=(char) x;
System.out.println(c);
数字字符转为整型数字
char c='1';
int x=c-48;
System.out.println(x);
排序
降序
Integer[] arr = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
Arrays.sort(arr,Collections.reverseOrder());
==和equals
==是判断两个变量是不是指向同一个内存空间
equals是判断两个变量指向的值是否相同
Integer A=new Integer(5);
Integer B=new Integer(5);
System.out.println(A==B);//false
System.out.println(A.equals(B));//true
Integer aaa=5;
Integer bbb=5;
System.out.println(aaa==bbb);//true
System.out.println(aaa.equals(bbb));//true
int a=10;
int b=10;
System.out.println(a==b);//true
String s1=new String("justice");
String s2=new String("justice");//和s1不同地址
String s3=s1;//和s1同一地址
System.out.println(s1==s2);//false
System.out.println(s1.equals(s2));//true
System.out.println(s1==s3);//true
System.out.println(s1.equals(s3));//true
大数
别忘记import java.math.BigInteger
Scanner sc=new Scanner(System.in);
BigInteger A=sc.nextBigInteger();//输入一个大整数
BigInteger B=BigInteger.TEN;//BigInteger中的常数
BigInteger C=BigInteger.valueOf(2);//用int赋初值
BigInteger D=new BigInteger("5");//用字符串构造大整数
BigInteger E=new BigInteger("1001", 2);//根据指定基数的字符串构造
System.out.println(E);
System.out.println(A.add(B));//加法
System.out.println(A.subtract(B));//减法
System.out.println(A.multiply(B));//乘法
System.out.println(A.divide(B));//除法
System.out.println(A.remainder(B));//取余
BigInteger[] dar=A.divideAndRemainder(B);//dar[0]=A/B,dar[1]=A%B
System.out.println(dar[0]+" "+dar[1]);
System.out.println(A.pow(3));//幂运算
System.out.println(A.or(B));//或
System.out.println(A.compareTo(B));//根据< = >返回-1 0 1
无穷大/小整数
int INF=int INF=Integer.MAX_VALUE;//2^31-1
int negINF=Integer.MIN_VALUE;//-2^31
保留小数
使用BigDecimal
BigDecimal bd=new BigDecimal(2.456);
bd=bd.setScale(2, RoundingMode.HALF_UP);//可选择多种保留方式,此种是四舍五入
使用String.format
double value=2.456;
System.out.println(String.format("%.2f", value).toString());
优先队列
每次从优先队列队首获取元素时,总是获取优先级最高的元素
自己定义元素的优先级,经常用于解决top K问题最小K个数
Queue<Integer> q=new PriorityQueue<> (k,(o1,o2)->o1-o2);
//第一个参数k是优先队列初始化大小
//第二个参数是一个lambda表达式,用于定义元素的优先级
//->前面的括号里是函数参数,->后是返回值,返回值<0为o1优先于o2
重写equals和hashCode
List重写equals
使用List里的contains方法会发现一些问题:
List<int[]> ls=new ArrayList<> ();
int[] a= {1,2};
int[] b= {1,2};
ls.add(a);
System.out.println(ls.contains(b));//false
List<int[]> ls=new ArrayList<> ();
int[] a= {1,2};
int[] b= a;
ls.add(a);
System.out.println(ls.contains(b));//true
两种结果不一样,因为contains方法比较的是两个对象引用,简而言之就是看两个对象是否地址相同。
查看ArrayList的contains源码可以发现其调用了equals方法,所以我们可以通过重写equals达到我们想要的效果。
class Point{
int x;
int y;
public Point(int x,int y) {
this.x=x;
this.y=y;
}
@Override
public boolean equals(Object obj) {
Point p=(Point) obj;
return this.x==p.x && this.y==p.y;
}
}
Map重写equals和hashCode
使用Map时,如果我们放入的key是自己写的类,必须重写equals方法和hashCode方法
正则表达式
移位运算
在计算机中,整数总是以二进制的形式表示。例如,int类型的整数7使用4字节表示的二进制如下:
00000000 00000000 00000000 00000111
可以对整数进行移位运算。对整数7左移1位得到整数14,左移两位得到整数28:
int n = 7;
int a = n << 1; // 00000000 00000000 00000000 00001110 = 14
int b = n << 2; // 00000000 00000000 00000000 00011100 = 28
int c = n << 28;// 01110000 00000000 00000000 00000000 = 1879048192
int d = n << 29;// 11100000 00000000 00000000 00000000 = -536870912
System.out.println(Integer.toString(a, 2));
System.out.println(Integer.toBinaryString(b));
System.out.println(Integer.toBinaryString(c));
System.out.println(Integer.toBinaryString(d));
左移29位时,由于最高位变成1,因此结果变成了负数。 类似的,对整数7进行右移,结果如下:
int n = 7; // 00000000 00000000 00000000 00000111 = 7
int a = n >> 1; // 00000000 00000000 00000000 00000011 = 3
int b = n >> 2; // 00000000 00000000 00000000 00000001 = 1
int c = n >> 3; // 00000000 00000000 00000000 00000000 = 0
如果对一个负数进行右移,最高位的1不动,结果仍然是一个负数:
int n = -536870912;
int a = n >> 1; // 11110000 00000000 00000000 00000000 = -268435456
int b = n >> 2; // 11111000 00000000 00000000 00000000 = -134217728
int c = n >> 28; // 11111111 11111111 11111111 11111110 = -2
int d = n >> 29; // 11111111 11111111 11111111 11111111 = -1
还有一种无符号的右移运算>>>,不管符号位,右移后高位总是补0。因此,对一个负数进行>>>,它会变成正数:
int n = -536870912;
int a = n >>> 1; // 01110000 00000000 00000000 00000000 = 1879048192
int b = n >>> 2; // 00111000 00000000 00000000 00000000 = 939524096
int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7
int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1
对byte和short类型进行移位时,会首先转换为int再进行移位。
左移实际上就是不断地×2,右移实际上就是不断地÷2。
在位运算的题目中,经常通过将整数右移i位,再 & 1,来获得整数的第i位。