我对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 ++?
感觉就像计算机应该能够做到这一点,因为事实上你可以用数字做到这一点。虽然它确实有更多的内存复杂性与字符串,所以如果不可能我不会太惊讶。
答案 0 :(得分:0)
查看OpenJKD,StringBuilder.toString()
(1)最终会调用new String(char[], offset, count)
(2),调用Arrays.copyOfRange
(3),它调用System.arrayCopy
。在某个级别,这将最终在内存中移动n个字节;但是,系统通常能够利用CPU级别的块复制命令,其执行速度比一次一个地复制n个字节要快。
我认为这个算法仍然是n^2
,因为你要复制1,然后是2,然后是3,......,然后是n个字节。我不认为你可以更快地完成你的目标,因为你有来复制这么多字节以填充数组。
字符串构建器实现肯定更高性能,因为在每一步,它将一个字节写入一个数组(已经正确调整大小!),然后将该数组复制到不同的内存位置。
答案 1 :(得分:-1)
但是,无论如何,从性能的角度来看,使用StringBuilder会更好。
当我做toString()
时,我观察到了这种情况。我观察到使用+
运算符构建String比使用StringBuilder
时花费更多时间。所以所有事情都说完了 - 即使时间复杂度相似,任何一天使用StringBuilder
都会更好。