Set操作的复杂性

时间:2010-10-24 22:01:43

标签: java set complexity-theory

这就是我在做的事:
字符串一=“一些字符串”
String two =“some string”

我想知道字符串一个两个中的所有字符,它们应该按顺序排列,因为它们在字符串一中

我编写了一个Java程序,通过使用Collections对集合执行set操作 我想知道执行集合运算的复杂性是多项式时间还是线性时间

我的节目在这里

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package careercup.google;

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

/**
 *
 * @author learner
 */
public class CharaterStringsIntersection {
    private static final String one = "abcdefgabcfmnx";
    private static final String two = "xbcg";

    public static void main(String args[]){
        List<Character> l_one = new ArrayList<Character>();
        List<Character> l_two = new ArrayList<Character>();

        for(int i=0; i<one.length(); i++){
           l_one.add(one.charAt(i));
        }
        for(int j=0; j<two.length(); j++){
            l_two.add(two.charAt(j));
        }

        l_one.retainAll(l_two);

        Iterator iter = l_one.iterator();
        while(iter.hasNext()){
            System.out.println(" > " + iter.next());
        }
    }
}

输出:

run:
 > b
 > c
 > g
 > b
 > c
 > x

4 个答案:

答案 0 :(得分:5)

其复杂度为O(N *(N + M)),其中N = one.length(),M = two.length()

它的工作方式如下:对于l_one的每个字符(其中有N个),它会扫描l_two(因为l_twoArrayList,扫描是线性,所以需要O(M)步,见[1])并在必要时从l_one移除项目(从ArrayList移除需要O(N),见[1]),所以你得到O(N *(N + M))。

您可以使用LinkedList l_one将复杂度降低到O(N * M)(因为从LinkedList删除是O(1),请参阅[2]),以及进一步 使用TreeSet l_two将其降低为O(N * log(M))(因为在TreeSet中搜索需要O(log(M)),参见[3])。< / p>

<强>参考文献:

  1. 所有其他操作均以线性时间运行ArrayList javadoc
  2. 所有操作都可以按照预期的方式执行双向链接,(LinkedList javadoc
  3. 此实现为基本操作(addremovecontainsTreeSet javadoc)提供了有保证的log(n)时间成本

答案 1 :(得分:4)

我认为你要问的更重要的问题是retainAll()函数的复杂性是什么。假设没有哈希或快速查找,我会假设时间复杂度为O(n ^ 2)。一个循环迭代列表,一个循环来比较每个项目。

答案 2 :(得分:1)

您使用的是错误的收藏品。

由于你使用普通ArrayList这样做,复杂性不会很好,我不知道内部实现,但我猜它是二次的(因为它必须滚动两个列表),除非Java在进行交集之前,在内部将两个列表转换为集合。

您应该从Set界面(here)开始,选择哪个系列更适合您的需求,我认为HashSet(常数时间)或{{1} (对数但能够保持自然排序)将是最好的解决方案。

答案 3 :(得分:0)

简言之:

  • ArrayList.add()O(1)

  • ArrayList.retainAll(other)O(N1 * N2),其中N1的大小为thisN2的大小为other。 (实际成本取决于保留的元素与去除元素的比例。)

  • 对于iter.hasNext()迭代器,
  • iter.next()O(1)ArrayList

这就像你期望的那样,基于对ArrayList作为Java数组的精神建模。