演算法比賽前必看必懂的演算法基礎知識 筆記總結(Java)
1、避免溢位,要記住各個資料型別的大小:
(1)byte:-128~127,1個位元組
(2)short:-32763~32767,2個位元組
(3)int:-21億多~21億多,4個位元組,(快速記憶:2開頭,10位數)
(4)long:(快速記憶:9開頭,19位數)
(5)float:保證小數前6位絕對精確,第7位一般也正確,第8位不一定
(6)double:保證小數前15~16位絕對精確
2、四捨五入:
(1)%.7f是四捨五入的
System.out.printf("%.6f",122.5432/13.9);//輸出8.816058 System.out.printf("%.7f",122.5432/13.9);//輸出8.8160576
(2)y四捨五入後要等於x的演算法表述:|y-x|<=5*10^(-t) ,(t就是x的小數位數+1)
例如:若x=0.624,則|y-x|<=0.0005
(3)兩個數相除之後要不要四捨五入的演算法表述:
例如: 122.5432/13.9,保留6位小數,不要四捨五入
BigDecimal a=new BigDecimal(122.5432);
BigDecimal b=new BigDecimal(13.9);
System.out.println(a.divide(b, 6, BigDecimal.ROUND_DOWN));//輸出8.816057
BigDecimal的八種舍入模式:
ROUND_HALF_UP: 四捨五入,遇到.5的情況時往上近似,例: 1.5 ->;2
ROUND_HALF_DOWN : 五舍六入,遇到.5的情況時往下近似,例: 1.5 ->;1
ROUND_FLOOR: 舍位時往負無窮 1.1-> 1 1.5-> 1 1.8-> 1ROUND_CEILING: 舍位時往正無窮方向移動 1.1-> 2 1.5-> 2 1.8-> 2
ROUND_DOWN: 直接拋棄位數,往0的方向靠近 1.1-> 1 1.5-> 1 1.8-> 1
ROUND_UP:與ROUND_DOWN,往遠離0的方向1.1-> 2 1.5-> 2 1.8-> 2
ROUND_HALF_EVEN:同樣以5為分界線,如果是5,則前一位變偶數
1.15-> 1.2 1.16-> 1.2 1.25-> 1.2 1.26-> 1.3
UNNECESSARY:無需舍位
3、進位制轉換:
(1)十進位制轉任意進位制:
String str=Integer.toBinaryString(a);//十轉二
String str=Integer.toOctalString(a);//十轉八
String str=Integer.toHexString(a);//十轉十六
(2)其他進位制轉十進位制:
String str=Interger.parseInt(s,n);//s是n進位制的string
(3)十六進位制轉八進位制:
萬萬不可十六進位制轉十,再由十轉八,如果數稍微大了轉成十進位制,十進位制數非常龐大,int型別就一定會溢位。
思路:十六轉二進位制,二進位制再轉八進位制。(轉成二進位制,陣列形式,不容易溢位)
十六進位制數str轉二進位制數str2具體程式碼:
public static String toBin(String str) {
int len_str = str.length();
StringBuilder str2 = new StringBuilder();
for (int i = 0; i < len_str; ++i) {
switch (str.charAt(i)) {
case '0':str2.append("0000");break;
case '1':str2.append("0001");break;
case '2':str2.append("0010");break;
case '3':str2.append("0011");break;
case '4':str2.append("0100");break;
case '5':str2.append("0101");break;
case '6':str2.append("0110");break;
case '7':str2.append("0111");break;
case '8':str2.append("1000");break;
case '9':str2.append("1001");break;
case 'A':str2.append("1010");break;
case 'B':str2.append("1011");break;
case 'C':str2.append("1100");break;
case 'D':str2.append("1101");break;
case 'E':str2.append("1110");break;
case 'F':str2.append("1111");break;
}
}
return str2.toString();
}
二進位制再轉八進位制具體程式碼:
(首先你要知道二轉八進位制的時候,對二進位制數是三位三位處理的,所以要把二進位制位數轉換成3的倍數,也就是前面加一些0)
if (len_str2 % 3 == 1) str2 = "00" + str2; //str2就是上面返回的二進位制數
else if (len_str2 % 3 == 2) str2 = "0" + str2;
處理完後,就可以轉成八進位制了:
public static void toOct(String str2){
int len=str2.length();
//如果八進位制的第一位為0,就不要輸出,不為0就輸出
int a=(str2.charAt(0)-'0')*4+(str2.charAt(1)-'0')*2+(str2.charAt(2)-'0');
if(a!=0)System.out.print(a);
//八進位制後面的幾位就不用考慮為不為0了
for(int i=3;i<len-2;i+=3){
a=(str2.charAt(i)-'0')*4+(str2.charAt(i+1)-'0')*2+(str2.charAt(i+2)-'0');
System.out.print(a);
}
}
4、長度不固定的陣列:
ArrayList<Integer> arr=new ArrayList<>();
arr.add(1);
arr.add(3);
5、把ArrayList陣列轉換成普通陣列:
int len=arr.size();
Integer[] newArr=arr.toArray(new Integer[len]);
6、一個String定位:
str.charAt(index);
一個int數字定位:
int a=3421;
個位=a%10, 十位=a/10%10, 百位=a/100%10
7、陣列arr1賦值給陣列arr2:
int[] arr1={1,2,3};
int[] arr2={4,5,6};
arr2=arr1.clone();
//絕對不可以直接arr2=arr1;這樣子arr1和arr2用的是同一個地址
8、求a和b的最小公倍數:
a×b÷(a和b的最大公因數)
9、求a和b的最大公因數:
int c=0;
while(b!=0){
c=a%b;
a=b;
b=c;
}
System.out.println("最小公倍數:"+a);
10、切斷一個String:
String str="abcdefghijklmn";
System.out.println(str.substring(4));//輸出efghijklmn
System.out.println(str.substring(3, 6));//輸出def
11、判斷某個char是大寫還是小寫:
char a='a';
System.out.println(Character.isUpperCase(a));
System.out.println(Character.isLowerCase(a));
12、char某個字母變大寫或者變小寫:
Character.toUpperCase(a);//變大寫
a-=32;//小寫變大寫
Character.toLowerCase(a)//變小寫
a+=32;//大寫變小寫
13、排序一個數組:
List<Integer> arr=new ArrayList<Integer>();
arr.add(1);arr.add(3);arr.add(2);
Collections.sort(arr);//正序排列
Collections.sort(arr,Collections.reverseOrder());//逆序排列
String [] str = {"a","e","f","g","h","i","b","c","d"};
Arrays.sort(str);//正序排列
Arrays.sort(str,Collections.reverseOrder());//逆序排列 注意:該方法只能用於string陣列型別,其他型別會報錯。
14、產生a~b範圍的隨機整數(含a也含b,就是[a,b]):
Math.round(Math.random()*(b-a)+a)
例如:產生1000~9999的隨機數
Math.round(Math.random()*8999+1000);
15、替換字串中的一部分:
StringBuilder str=new StringBuilder("abcdefghijklmn");
str=str.replace(3, 6, "這裡被換了");//變成了abc這裡被換了ghijklmn
16、格式化數字:
DecimalFormat df = new DecimalFormat("#00.00#0#");
System.out.println(df1.format(12.345));
0 代表一個位 ,不存在也得顯示0# 一個位,不存在就不顯示
. 小數的分隔符的佔位符
17、邊放數字邊排好序:
PriorityQueue<Integer> arr=new PriorityQueue<>();
arr.add(6);
arr.add(3);
arr.add(8);
arr.add(9);
System.out.println(arr.peek());//3 彈出第一個,不刪除
System.out.println(arr);//[3, 6, 8, 9]
arr.poll(); //彈出第一個,同時刪除
System.out.println(arr);//[6, 9, 8]
18、數字n的科學表示法:
String str=String.format("%.6E",n);
19、日曆:(假設當前時間為2018/3/30,週五)
Calendar rightNow = Calendar.getInstance();
System.out.println(rightNow.get(Calendar.YEAR));//2018
System.out.println(rightNow.get(Calendar.MONTH)+1);//3
System.out.println(rightNow.get(Calendar.DAY_OF_MONTH));//30
System.out.println(rightNow.get(Calendar.DAY_OF_WEEK));//6
rightNow.add(Calendar.DATE, -1);//調整rightNow為2018年3月29日
rightNow.add(Calendar.YEAR, 1);//調整rightNow為2019年3月29;
rightNow.set(calendar.get(Calendar.YEAR), 6, 1);//設定rightNow為2018年6月1日
rightNow.setTime(new Date(123,11,31));//設定rightNow為 2023 ,2023=(19+1)23