No, the length of a java string is O(1) because java's string class stores the length as a field.
The advice you've received is true of C, amongst other languages, but not java. C's strlen walks the char array looking for the end-of-string character. Joel's talked about it on the podcast, but in the context of C.
Answer from sblundy on Stack OverflowNo, the length of a java string is O(1) because java's string class stores the length as a field.
The advice you've received is true of C, amongst other languages, but not java. C's strlen walks the char array looking for the end-of-string character. Joel's talked about it on the podcast, but in the context of C.
Contrary to what has been said so far, there is no guarantee that String.length() is a constant time operation in the number of characters contained in the string. Neither the javadocs for the String class nor the Java Language Specification require String.length to be a constant time operation.
However, in Sun's implementation String.length() is a constant time operation. Ultimately, it's hard to imagine why any implementation would have a non-constant time implementation for this method.
It is O(1) as the length is already known to String instance.
From JDK 1.6 it is visible.
public int length() {
return count;
}
Update
It is important to understand why they can cache the value of count and keep using same value for count. The reason lies in a great decision they took when designing String, its Immutability.
In Java any String is backed up by an final array. So it is simple to just return the array length. So it is O(1) complexity. And if you think in your code
for(int i=0; i<s.length()-1;i++){
//some code here!
}
s.length() is called for every iteration then you are not right. Modern compiler optimizes this type of call and changes s.length() to constant number(i.e the length of the String instance).
Let n be the number of characters in your string. Your loop obviously iterates n times (since text.length() == n), with each iteration doing constant work (addition).
Your loop should be O(n)
EDIT: The other answers are wrong. You are not returning a string, nor appending to a StringBuilder. You are adding the int value of each ASCII character, and returning the total.
It's O(n). However, a simple change can make it O(1) here. Change the method body to return text;. String is immutable; creating a copy character by character is pointless.
Hi, I'm working on an exercise problem in my class; the problem asked me to create an algorithm to find the "maximum consecutive increasingly ordered substring" of an inputted string. Basically, it wants me to find the longest substring in a string where the letters are in alphabetical order.
I managed to implement the algorithm, but I'm not sure what the time complexity of it is.
public static String maxConsecutiveOrderedSubstring(String str)
{
String subStr = "";
for (int i = 0; i < str.length() - 2; i++)
{
// Read in the letter at the index
String test = "" + str.charAt(i);
// Read the following letters
for (int j = i + 1; j < str.length(); j++)
{
// If the next letter is before the current letter, break the loop
if (str.charAt(j - 1) + 1 > str.charAt(j))
break;
test += str.charAt(j);
}
// If the substring just tested is longer than the one currently stored,
// replace the currently stored string.
if (test.length() > subStr.length())
subStr = test;
// Move the current index forwards by the amount of letters read in
i += test.length() - 1;
}
return subStr;
}At first I thought it was O(n2) because it has two loops. But I realized that the algorithm actually runs through the inputted string only once, because of i += test.length() - 1;
Am I correct in thinking that this algorithm has a time complexity of O(n)?
New answer
As of update 6 within Java 7's lifetime, the behaviour of substring changed to create a copy - so every String refers to a char[] which is not shared with any other object, as far as I'm aware. So at that point, substring() became an O(n) operation where n is the numbers in the substring.
Old answer: pre-Java 7
Undocumented - but in practice O(1) if you assume no garbage collection is required, etc.
It simply builds a new String object referring to the same underlying char[] but with different offset and count values. So the cost is the time taken to perform validation and construct a single new (reasonably small) object. That's O(1) as far as it's sensible to talk about the complexity of operations which can vary in time based on garbage collection, CPU caches etc. In particular, it doesn't directly depend on the length of the original string or the substring.
It was O(1) in older versions of Java - as Jon stated, it just created a new String with the same underlying char[], and a different offset and length.
However, this has actually changed started with Java 7 update 6.
The char[] sharing was eliminated, and the offset and length fields were removed. substring() now just copies all the characters into a new String.
Ergo, substring is O(n) in Java 7 update 6
For example, substring's Big O complexity is O(n), while charAt is O(1). I checked the docs and they don't mention complexity. Did the people that write those answers on SO inspect the source code of the String API to figure the complexity out?
For every call to String.concat(), a new string instance is created. To create that instance, the contents of the previous string needs to be copied to the new one plus the contents of the concatenated string. This is done for every string in the collection. So if you look at in in terms of how many strings are concatenated (and not the characters copied), you're copying the contents of the n strings by the time you reach the nth iteration and all that matters is the worst case (the last iteration). Therefore it has \$O(n^2)\$ performance.
As Jeff points out a new string is created every time you do += on the string.
And thus correctly explains why the complexity is O(2)
The key point is the java.lang.String is not mutable.
Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.
So any attempt to modify it generated a completely new string (which to programmers in most other languages is strange).
The solution is to use the java.lang.StringBuffer. This behaves like most other languages string object and allows mutation. The objective is to build a string inside a StringBuffer and when you are finally finished covert this into a string.
A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls.
Looking at OpenJKD, StringBuilder.toString() (1) ends up calling new String(char[], offset, count) (2), which calls Arrays.copyOfRange (3), which calls System.arrayCopy. At a certain level, this is going to end up moving n bytes in memory; however, the system is often able to utilize CPU-level block copy commands, which executes more quickly than copying n bytes one-at-a-time.
I think this algorithm is still n^2, since you're copying 1, then 2, then 3, ..., then n bytes. I don't think you can accomplish your goal any more quickly, since you have to copy this many bytes in order to fill out the array.
The string builder implementation is definitely more performant, since at each step, it writes a single byte into an array (that is already sized correctly!), and then copies that array to a different memory location.
But, in any case, from a performance point of view, using StringBuilder is better.
I have observed this to be the case when I did toString()s. I observe that building a String using the + operator takes more time than when we use StringBuilder. So everything said and done - even if the time complexity is similar, using StringBuilder is better any day.
Since you have both objects already, the time complexity is the same: it's O(1), because both java.lang.String and Java arrays store their length for direct retrieval.
However, you can improve upon the timing of your method by using getChars method of the string to avoid copying the characters past the end of the substring that you need:
int maxLength = 100;
int effectiveLength = Math.min(maxLength, str.length());
char[] strArray = new char[effectiveLength];
str.getChars(0, effectiveLength, strArray, 0);
If it happens that your algorithm can stop processing before reaching the end of the string, this approach would let you avoid allocating the extra memory and copying the characters into it.
That depends on how the method is implemented and the Java API gives no guarantees for that.
The current implementation is that toCharArray() will give you a copy of the String's underlying buffer, so it's a very expensive operation (memory allocation + copy many bytes), especially compared to str.length() which just returns the value of an internal final field (at least in Java 6).
In Java 7+, they seem to have stopped sharing the underlying character array (now, substr() always makes a copy).