1. 程式人生 > >演算法比賽前必看必懂的演算法基礎知識 筆記總結(Java)

演算法比賽前必看必懂的演算法基礎知識 筆記總結(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-> 1   
ROUND_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