【发布时间】:2016-09-29 20:46:09
【问题描述】:
我有一个关于 Java 字符串的非常具体的问题。 给定一个字符串,我希望能够创建一个字符串数组,这样每个第 i 个元素都是一个由给定字符串的前 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++?
感觉就像一台计算机应该能够做到这一点,因为你实际上可以用数字做到这一点。虽然它确实对字符串有更多的内存复杂性,所以如果它不可能,我不会太惊讶。
【问题讨论】:
-
那些不是列表(在标题中),它们是数组。
-
看看this answer。制作字符串的任何副本都是 O(n) 解决方案。
-
不是答案,而是有趣的琐事。在 C++ 中,标准非常鼓励 COW,但后来它发生了变化,并且是不允许的。 GCC 在 GCC 5 之前是不兼容的。(因此,使用 GCC 4.* 在 C++ 中复制字符串是 O(1))。
-
如果您想要一种更智能的数据分配语言,那么您应该研究专注于不可变类型的语言(往往是函数式语言)。可变性会阻止代码对数据变得聪明。
-
在任何情况下,如果您正在编写 n 个长度为 1 到 n 的字符串,最坏情况的复杂度将是 O(n²)。
标签: java string algorithm list complexity-theory