高质量代码《二》
摘自《剑指Offer》,读者根据自己笔试在OJ平台答题中遇到的常见问题进行总结,OJ平台来自牛客网
代码的鲁棒性
常见的问题
1、 int 计算时超过上限 2^31 ≈ 2*10^9
2、 使用包装类 Integer 常量池 超过-128 ~127的数进行比较
3、 数的值大于long上限
4、 计算精度 如 int /int 会有舍入误差
ans1、 使用 long 或者 BigInteger或者自行处理避免超过
ans2、 使用equals做检查
ans3、 BigInteger
ans4、 计算时 转为double,最后在进行舍入误差
Java容器
容器的最大容量为Integer_MAX
不过一旦超过2*10^6次方,想想是不是可以不用容器实现! 对
知识点: Integer
当值超过127 以后,就只能用equals!
public static void main(String[] args) {
Integer i = 127;
Integer a = 127;
System.out.println((int)a==(int)i); //true
System.out.println(a==i);//true
System.out.println(a.equals(i));//true
// Integer i = 128;
// Integer a = 128;
// System.out.println((int)a==(int)i); true
// System.out.println(a==i); false
// System.out.println(a.equals(i)); true
}
}
华为机考平均数
从输入任意个整型数,统计其中的负数个数并求所有非负数的平均值,结果保留一位小数,如果没有非负数,则平均值为0
本题有多组输入数据,输入到文件末尾,请使用while(cin>>)读入
数据范围小于1e6
输入描述:
输入任意个整数,每行输入一个。
输出描述:
输出负数个数以及所有非负数的平均值
注意:
1、如果累加会超出范围(所以可以average(i) = averager(i-1) * (i/i-1)) + num(i)/i ;
2、输入整数个数没有限制,使用long;
3、int/int仍然是int
[剑指 Offer 22. 链表中倒数第k个节点]
简单的双指针问题就会导致3个问题
1、输入头节点为null
2、K=0
3、K如果大于节点个数
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if(head == null || k ==0){
return null;
}
ListNode p1 = head;
ListNode p2 = head;
for( int i = 0; i < k-1 ; i++){
if(p2.next == null){
return null;
}else{
p2 = p2.next;
}
}
while(p2.next!=null){
p1=p1.next;
p2=p2.next;
}
return p1;
}
}
注意细节: 有些时候简单的边界,可以通过测试案例来调整,不用非得想明白(简单用例自己也可以手做)
常见的鲁棒性
1、输入为空
2、输入值大于容器容量
3、过程中没有考虑超出范围
(这些应该是再测试时候想到!)
所以先提前想好,举例子,解决步骤,异常情况,可以交流以后。然后下笔!
华为题目:等差数列
功能:等差数列 2,5,8,11,14。。。。
输入:正整数N >0
输出:求等差数列前N项和
本题为多组输入,请使用while(cin>>)等形式读取数据
输入描述:
输入一个正整数。
输出描述:
输出一个相加后的整数。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Scanner;
//万一输入的不是整数呢?
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //读出来就是str
String str ;
while ((str=br.readLine())!=null){
if (str=="0"){
break;
}
BigInteger a = new BigInteger( str);
BigInteger b = new BigInteger( str);
BigInteger three = new BigInteger( "3");
BigInteger one = new BigInteger( "1");
BigInteger two= new BigInteger( "2");
a= a.multiply(three);
a =a.add(one);
b =b.multiply(a); //这里出问题了 int/int 为整数
System.out.println(b.divide(two));
}
}
}