https://leetcode-cn.com/problems/string-to-url-lcci/
拿到题,弄不清楚真实长度是什么意思,后来看了解题才明白,就是后面的字符串没用的意思。
不太明白这个题是在考察什么。
于是写下了下面的代码
后来觉得这也太差了,看了大家的解体思路改成了下面的代码
然后就思考这个题到底是想考察什么。
那不能白做吧,那只能强行加戏了,来看看第一个为啥这么慢吧。
String.substring(startIndex: Int, endIndex: Int): String
/**
* Returns a string that is a substring of this string. The
* substring begins at the specified {@code beginIndex} and
* extends to the character at index {@code endIndex - 1}.
* Thus the length of the substring is {@code endIndex-beginIndex}.
* <p>
* Examples:
* <blockquote><pre>
* "hamburger".substring(4, 8) returns "urge"
* "smiles".substring(1, 5) returns "mile"
* </pre></blockquote>
*
* @param beginIndex the beginning index, inclusive.
* @param endIndex the ending index, exclusive.
* @return the specified substring.
* @exception IndexOutOfBoundsException if the
* {@code beginIndex} is negative, or
* {@code endIndex} is larger than the length of
* this {@code String} object, or
* {@code beginIndex} is larger than
* {@code endIndex}.
*/
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(this, beginIndex);
}
if (endIndex > length()) {
throw new StringIndexOutOfBoundsException(this, endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
// Android-changed: Use native fastSubstring instead of String constructor.
return ((beginIndex == 0) && (endIndex == length())) ? this
: fastSubstring(beginIndex, subLen);
}
// BEGIN Android-added: Native method to access char storage managed by runtime.
@FastNative
private native String fastSubstring(int start, int length);
// END Android-added: Native method to access char storage managed by runtime.
从上面的代码开出,substring,一个拓展函数,最后调用fastSubstring的native函数
然后我们来看看replace如何实现的
/**
* Returns a new string obtained by replacing all occurrences of the [oldValue] substring in this string
* with the specified [newValue] string.
*/
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun String.replace(oldValue: String, newValue: String, ignoreCase: Boolean = false): String {
run {
var occurrenceIndex: Int = indexOf(oldValue, 0, ignoreCase)
// FAST PATH: no match
if (occurrenceIndex < 0) return this
val oldValueLength = oldValue.length
val searchStep = oldValueLength.coerceAtLeast(1)
val newLengthHint = length - oldValueLength + newValue.length
if (newLengthHint < 0) throw OutOfMemoryError()
val stringBuilder = StringBuilder(newLengthHint)
var i = 0
do {
stringBuilder.append(this, i, occurrenceIndex).append(newValue)
i = occurrenceIndex + oldValueLength
if (occurrenceIndex >= length) break
occurrenceIndex = indexOf(oldValue, occurrenceIndex + searchStep, ignoreCase)
} while (occurrenceIndex > 0)
return stringBuilder.append(this, i, length).toString()
}
}
看到replace使用容量可变的字符串stringbuilder实现的,这可能就是效率不高的问题所在吧