Java - 创建长度增加的字符串列表的时间复杂度

时间:2016-09-29 20:46:10

标签: java string algorithm list complexity-theory

我对Java中的字符串有一个非常具体的问题。 给定一个字符串,我希望能够创建一个字符串数组,这样每个元素都是一个由给定字符串的前i个字符组成的字符串。像这样:

public static String[] substrings(String s){
    String[] list = new String[s.length()];
    list[0] = "" + s.charAt(0);
    for (int i = 1; i < s.length(); i++)
        list[i] = list[i-1] + s.charAt(i);
    return list;
}

但我听说添加字符串和'+'有时间复杂度O(n)。这意味着我的方法具有时间复杂度O(n²)。另一种方法可能是使用StringBuilder对象。像这样:

public static String[] substrings(String s){
    String[] list = new String[s.length()];
    StringBuilder sb = new StringBuilder(s.length());
    for (int i = 0; i < s.length(); i++){
        sb.append(s.charAt(i));
        list[i] = sb.toString();
    }
    return list;
}

但我觉得StringBuilder.toString()的时间复杂度为O(n),这意味着该方法仍然具有时间复杂度O(n²)。虽然我不确定这个,所以如果我错了,请纠正我。

如果我对此是正确的,有没有办法在Java中构建字符串,并且有一些所有值的日志,这不需要时间复杂度O(n²)?

如果没有,有没有办法用另一种编程语言,最好是C或C ++?

感觉就像计算机应该能够做到这一点,因为事实上你可以用数字做到这一点。虽然它确实有更多的内存复杂性与字符串,所以如果不可能我不会太惊讶。

2 个答案:

答案 0 :(得分:0)

查看OpenJKD,StringBuilder.toString()1)最终会调用new String(char[], offset, count)2),调用Arrays.copyOfRange3),它调用System.arrayCopy。在某个级别,这将最终在内存中移动n个字节;但是,系统通常能够利用CPU级别的块复制命令,其执行速度比一次一个地复制n个字节要快。

我认为这个算法仍然是n^2,因为你要复制1,然后是2,然后是3,......,然后是n个字节。我不认为你可以更快地完成你的目标,因为你来复制这么多字节以填充数组。

字符串构建器实现肯定更高性能,因为在每一步,它将一个字节写入一个数组(已经正确调整大小!),然后将该数组复制到不同的内存位置。

答案 1 :(得分:-1)

但是,无论如何,从性能的角度来看,使用StringBuilder会更好。

当我做toString()时,我观察到了这种情况。我观察到使用+运算符构建String比使用StringBuilder时花费更多时间。所以所有事情都说完了 - 即使时间复杂度相似,任何一天使用StringBuilder都会更好。