使用不同方法查詢陣列中某個特定值,並計算時間(改正二分法查詢錯誤和陣列轉化集合錯誤)

raylu666發表於2017-04-15

這裡修正剛才寫的程式碼,發現很多根本沒找到。。。程式碼有很多問題,這裡一個個修正並記錄寫來:


1. 使用二分法時一定要先排序

錯誤的寫法:

public int search() {  
        return Arrays.binarySearch(arr, targetValue);  
    }  
改正後寫法:

	public int search() {
		//System.out.println("arrLength"+ arr.length);
		Arrays.sort(arr);
		return Arrays.binarySearch(arr, targetValue);
	}

2.陣列轉化為List錯誤:  要使用Integer[], 不要使用int[]

int[]陣列使用Arrays.asList()時會有問題,會把整個陣列轉化為List的一個元素,並沒有把陣列內的內容變成一個個List元素
錯誤的寫法:

int[] arr = new int[1000]; 
List list = Arrays.asList(arr); //這樣寫arr[]就會變成list的第一個元素了。。整個list.size()=1;不符合預期
改正後寫法:

Integer[] arr = new Integer[10000];

List list = Arrays.asList(arr);//陣列轉化成List

Set set = new HashSet(Arrays.asList(arr));//陣列轉化成Set

根據改正後的程式碼重新計算哪種方式查詢最快,陣列比較短時建議Loop,遍歷比較長的陣列可以用List

1.當陣列長度100時,Loop最快

使用Loop查詢花費的時間為15360
使用Arrays.binarySearch()查詢花費的時間為440319
使用UseList查詢花費的時間為349013
使用UseSet查詢花費的時間為257706
2.當陣列長度1000時,Loop最快,List次之
使用Loop查詢花費的時間為125867
使用Arrays.binarySearch()查詢花費的時間為1839786
使用UseList查詢花費的時間為235946
使用UseSet查詢花費的時間為1150720

3.當陣列長度10000時,Loop最快,List次之

執行第一次:

使用Loop查詢花費的時間為463787
使用Arrays.binarySearch()查詢花費的時間為9032957
使用UseList查詢花費的時間為693333
使用UseSet查詢花費的時間為5693011

執行第二次:

使用Loop查詢花費的時間為191573
使用Arrays.binarySearch()查詢花費的時間為15807140
使用UseList查詢花費的時間為154027
使用UseSet查詢花費的時間為4534185

4.當陣列長度1000000時, List比較快且相對穩定

執行第一次:

使用Loop查詢花費的時間為4186451
使用Arrays.binarySearch()查詢花費的時間為629270345
使用UseList查詢花費的時間為167680
使用UseSet查詢花費的時間為86613297

執行第二次:

使用Loop查詢花費的時間為5113171
使用Arrays.binarySearch()查詢花費的時間為624438347
使用UseList查詢花費的時間為18483192
使用UseSet查詢花費的時間為89199322

貼上修正後的程式碼

測試主程式碼:

package test1;

import java.util.Arrays;
import java.util.List;

//在陣列中查詢某個特定值,如何查詢最快?測試看看。。
//如何在陣列中找出某個特定值,並計算執行時間
public class TestQuery1 {
	public static void main(String[] args) {
		//定義一個含有10000個數字的陣列
		//int[] arr = new int[10000];//此方式無法by單個數字存入List
		Integer[] arr = new Integer[1000000];
		
		for(int i = 0; i < arr.length; i++){
			arr[i] = (int) (Math.random()*100000000);
		}

		List list = Arrays.asList(arr);
		//假設查詢數字666
		int targetValue = 666;
		
		//使用Loop查詢時間
		UseLoop useLoop = new UseLoop(arr, targetValue);
		useLoop.spendTime("Loop");
		
		//使用Arrays.binarySearch()方法查詢
		UseArraysBinary  useAB = new UseArraysBinary(arr, targetValue);
		useAB.spendTime("Arrays.binarySearch()");

		//使用集合List查詢
		UseList useList = new UseList(arr, targetValue);
		useList.spendTime("UseList");
		
		//使用集合set查詢
		UseSet useSet = new UseSet(arr, targetValue);
		useSet.spendTime("UseSet");
	}
}
計算時間程式碼,搞成抽象類了

package test1;

public abstract class SpendTime {
	
	protected Integer[] arr;
	protected int targetValue;
	
	public abstract int search();
	
	public void spendTime(String name){
		long start = System.nanoTime();
	//	System.out.println("如果是正數表示包含這個值:"+search());
		search();
		long end = System.nanoTime();
		long time = end - start;
		System.out.println("使用"+name+"查詢花費的時間為"+time);
	}
}
package test1;

public class UseLoop extends SpendTime{
//使用Loop查詢陣列是否包含某個值

	public UseLoop(Integer[] arr, int targetValue){
		this.arr = arr;
		this.targetValue = targetValue;
	}

public int search() {
		for(int i =0; i < arr.length; i++){
			if (arr[i]== targetValue){
		//		System.out.println(arr[i]);
				return i;
			}
		}
		return -1;
	}
}

使用Arrays.binarySearch()方法

package test1;

import java.util.Arrays;

public class UseArraysBinary extends SpendTime{
	public UseArraysBinary(Integer[] arr, int targetValue){
		this.arr = arr;
		this.targetValue = targetValue;
	}
	//使用Arrays.binarySearch查詢陣列中是否含有特定值
	@Override
	public int search() {
		//System.out.println("arrLength"+ arr.length);
		Arrays.sort(arr);
		return Arrays.binarySearch(arr, targetValue);
	}
}

使用List.contains()方法

package test1;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class UseList extends SpendTime{

	public UseList(Integer[] arr, int targetValue){
		this.arr = arr;
		this.targetValue = targetValue;
	}
	
	@Override
	public int search() {
		List list = Arrays.asList(arr);
		if(list.contains(targetValue))
			return 1;
		return -1;
	}
}

使用Set.contains()方法
package test1;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class UseSet extends SpendTime{
	public UseSet(Integer[] arr, int targetValue){
		this.arr = arr;
		this.targetValue = targetValue;
	}
	@Override
	public int search() {
		Set set = new HashSet(Arrays.asList(arr));
	//	System.out.println(set.size());
		if(set.contains(targetValue))
			return 1;
		return -1;
	}
}



相關文章