zoukankan      html  css  js  c++  java
  • 如何高效检查一个数组中是否包含某个值?

    转载地址:http://www.diguage.com/archives/112.html

    1、不同的实现方式

    1) 使用List

    public static boolean useList(String[] arr, String targetValue) {
           return Arrays.asList(arr).contains(targetValue);
    }
    2) 使用Set

    public static boolean useSet(String[] arr, String targetValue) {
          Set<String> set = new HashSet<String>(Arrays.asList(arr));
          return set.contains(targetValue);
    }
    3) 使用循环:

    public static boolean useLoop(String[] arr, String targetValue) {
        for (String s : arr) {
            if (s.equals(targetValue)) {
                return true;
            }
        }
        return false;
    }
    4) 使用Arrays.binarySearch

    public static boolean useArraysBinarySearch(String[] arr, String targetValue) {
        int a = Arrays.binarySearch(arr, targetValue);
        if (a > 0) {
            return true;
        } else {
            return false;
        }
    }

    2、时间复杂度

    使用如下代码来粗略比较不同实现间的时间复杂度。虽然不是很精确,但是思路确实正确的。我们将看看数组在有5、1k、10k个元素的情况下的不同表现。

    public static void main(String[] args) {
        String[] arr = new String[]{"CD", "BC", "EF", "DE", "AB"};
    
        // use list
        long startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useList(arr, "A");
        }
        long endTime = System.nanoTime();
        long duration = endTime - startTime;
        System.out.println("useList:  " + duration / 1000000);
    
        // use set
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useSet(arr, "A");
        }
        endTime = System.nanoTime();
        duration = endTime - startTime;
        System.out.println("useSet:  " + duration / 1000000);
    
        // use loop
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useLoop(arr, "A");
        }
        endTime = System.nanoTime();
        duration = endTime - startTime;
        System.out.println("useLoop:  " + duration / 1000000);
    
        // use Arrays . binarySearch ()
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useArraysBinarySearch(arr, "A");
        }
        endTime = System.nanoTime();
        duration = endTime - startTime;
        System.out.println("useArrayBinary:  " + duration / 1000000);
    }
    结果:

    useList:  12
    useSet:  65
    useLoop:  2
    useArrayBinary:  7

    使用大一点的数组(1k个元素):

    int length = 1000;
    String[] arr = new String[length];
    
    Random s = new Random();
    for (int i = 0; i < length; i++) {
        arr[i] = String.valueOf(s.nextInt());
    }
    结果:
    useList:  115
    useSet:  2010
    useLoop:  97
    useArrayBinary:  9
    使用更大一点的元素(10k个元素):

    int length = 10000;
    String[] arr = new String[length];
    
    Random s = new Random();
    for (int i = 0; i < length; i++) {
        arr[i] = String.valueOf(s.nextInt());
    }

    结果:

    useList:  1678
    useSet:  25609
    useLoop:  1802
    useArrayBinary:  10
    从上面的结果可以清晰看到,使用简单循环的相比使用其他集合操作更高效。很多很多开发人员使用第一种方法,但是它并不是最高效的。将数组转化成其他的任何集合类型都需要先将所有元素读取到集合类中,才能对这个集合类型做其他的事情。

    当使用Arrays.binarySearch()方法时,数组必须是排好序的。如果数组不是排好序的,则不能使用这个方法。

    事实上,如果你真的需要高效地检查一个数组或者集合中是否包含一个值,一个排好序的数组或者树可以达到O(log(n))的时间复杂度,HashSet甚至能达到O(1)的时间复杂度。


  • 相关阅读:
    CHtmlEditCtrl (3): More HTML Editor Options
    CHtmlEditCtrl (2): Add a Source Text Editor to Your HTML Editor
    CHtmlEditCtrl(1) : Use CHtmlEditCtrl to Create a Simple HTML Editor
    HttpWebRequest抓取网页数据返回异常:远程服务器返回错误: (503) 服务器不可用
    HttpWebRequest: Remote server returns error 503 Server Unavailable
    所有的图片后缀名
    system函数的应用一例
    esUtil.h中的m变量报错
    IIS通过HTML5实现应用程序缓存的离线浏览
    鼠标悬浮在img上让图片变大
  • 原文地址:https://www.cnblogs.com/archermeng/p/7537228.html
Copyright © 2011-2022 走看看