踩坑记录
1 2 3 4 5 6 7
| 1. 3/2.0、1.0*3/2 都可以是1.5。 但是3/2*1.0不行,因为是先3/2强制取整变成1后再*1.0变为1.0。 所以要注意先后顺序。 2. 做题时,先看看能不能采用即时处理。 如果想着先全部处理完再输出很可能超时,但如果是一边处理判断一边输出则不容易超时 https://blog.csdn.net/RP123123123/article/details/122272967
|
可以用 int数组 代替 HashMap
常用于对字符串进行操作的算法题中,用来实现滑动窗口
目的: 提高效率,也更便于操作value
为什么可以这样做??
因为字符型ascii码最高就到128,所以只要创建一个占据128内存的数组就行,所占空间少。
其次字符型可以根据ascii码转成int,此时数组的下标所对应的字符(通过ascii码)就是key,下标对应的值就是value。例如a[65]=5
相当于 key=’A’,value=5
判断一个数是否是整数
1 2 3 4
| if(s == (int) s){ return 整数 }
|
判断素数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public boolean prime(int num){ if(num <= 1){ return false; } for(int i = 2; i <= (int)Math.sqrt(num); i++){ if(num % i == 0){ return false; } } return true; }
|
反转数字
1 2 3 4 5 6 7 8 9
| public int reverse(int num){ int ans = 0; while(num > 0){ ans = ans*10 + (num%10); num = num/10; } return ans; }
|
浮点数取整
- Math.ceil(double n); //对浮点数向上取整
- Math.floor(double n); //对浮点数向下取整
- Math.round(double n); //对浮点数四舍五入取整,不够准确。例如:-11.5 -> -11
利用大数类进行准确的四舍五入
1 2
| //对10.7进行四舍五入取整 new BigDecimal("10.7").setScale(0,BigDecimal.ROUND_HALF_UP).intValue();
|
求最大公约数和最小公倍数
- 最大公约数:比如说 15和12 的最大公约数 是 3
- 最小公倍数:比如说 2 和 5 的最小公倍数 是 10
- 最小公倍数 = a*b/a和b的最大公约数
最大公约数的实现 —— 辗转相除法(欧几里得算法)
1 2 3 4 5
| 1. c = a % b; 2. 若 c == 0 ,则 b 是 a和b 的最大公约数 3. 若 c != 0 ,则 令 a = b,b = c,再次执行第一步。
若要求最小公倍数,则在求出最大公约数后,用 最小公倍数 = a*b/a和b的最大公约数
|
最大公约数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public int GCD(int a,int b){ int t,c; if(a < b){ t = a; a = b; b = t; } while(a%b != 0){ c = a % b; a = b; b = c; } return b; }
|
最小公倍数
1 2 3
| public int LCM(int a,int b){ return a*b/GCD(a,b); }
|
四舍五入
- Math.ceil(double n); //对浮点数向上取整
- Math.floor(double n); //对浮点数向下取整
- Math.round(double n); //对浮点数四舍五入取整,不够准确。例如:-11.5 -> -11
利用大数类进行准确的四舍五入
1 2
| //对10.7进行四舍五入取整 new BigDecimal("10.7").setScale(0,BigDecimal.ROUND_HALF_UP).intValue();
|
去重
- 用Set判断是否已经存在,若存在则不进行操作
1 2 3 4 5 6 7 8
| public void distinct(int[] a){ Set<Integer> set = new HashSet<>(); for(int x : a){ if(set.add(x)){ System.out.println(x); } } }
|
- 用Stream流
1 2 3 4 5 6
| public void distinct(int[] a){ List<Integer> alist = Arrays.stream(a).distinct().collect(Collectors.toList()); for(int x : alist){ System.out.println(x); } }
|
快速输入和快速输出 —— BufferedReader和 BufferWriter
输入 —— BufferedReader
1 2 3 4 5 6
| BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 实例化 String/char/int s1 = in.read(); 读入一个字符。可单独读入空格或回车,回车会留下来被下次读取接收(吸收一个\n留下一个\r) String s2 = in.readLine(); 读入一行,可读入空格。遇到回车结束,且回车会被舍弃,不会再被下次读取 String[] ss = in.readLine().split(" "); 将读入的一行字符串以空格分为字符串数组 …… in.close(); 关闭流
|
需要注意的是:
- 在windows中按一下回车键,一共有两个字符 “\n\r”,而read()只能读取一个字符所以如要用read来达到吸收回车的目的,需要用两个read(); 如果用readLine()的话会将”\n\r”全部吸收 , 所以只需要一个readLine()来吸收回车。
- 由于是字符型,用read()读取整型时,读取0会显示其as码48,读取9以上的数就会出问题了。所以我们应该用readLine()来接收,再利用Integer.parseInt()转化为整型
输出 —— BufferWriter
1 2 3 4 5 6 7 8 9
| BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out)); 实例化 out.write(x); out.write(" "); out.write("\n"); out.write(x+"\n"); …… out.flush(); 在程序最后刷新一次即可,确保缓冲区的数据全部被输出 out.close(); 先刷新后关闭
|
需要注意的是:
- write()不能直接输出int类型。因为BufferWriter是字符型流,直接用write(int a) 会输出其对应的ASCii码的字符 ,比如输出 65 会显示 A。可以通过write(String.valueOf(a)) 或 write(a+””)实现
记得在类声明后进行异常处理,throws IOException
原理类似于System.out.printf();
1 2
| String s1 = String.format("%.2f\n",10.34567); String s2 = String.format("你的名字是:%s\n","丁梓航");
|
求集合的交集、差集、并集
交集 —— retainAll()
1 2 3 4
| se1.retainAll(set2) set1 = {1,2,3,7},set2 = {1,3,8,9} => set1 = {1,3}
|
差集 —— removeAll()
1 2 3 4
| se1.removeAll(set2) set1 = {1,2,3,7},set2 = {1,3,8,9} => set1 = {2,7}
|
并集 —— addAll()
1 2 3 4
| se1.addAll(set2) set1 = {1,2,3,7},set2 = {1,3,8,9} => set1 = {1,2,3,7,8,9}
|