java:使用StringBuilder在开头插入
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java:使用StringBuilder在开头插入相关的知识,希望对你有一定的参考价值。
我只能用String执行此操作,例如:
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
有没有办法用StringBuilder实现这个目的?谢谢。
StringBuilder sb = new StringBuilder();
for(int i=0;i<100;i++){
sb.insert(0, Integer.toString(i));
}
警告:它违背了StringBuilder
的目的,但它完成了你的要求。
更好的技术(虽然仍然不理想):
- 反转要插入的每个字符串。
- 将每个字符串附加到
StringBuilder
。 - 完成后反转整个
StringBuilder
。
这将把O(n²)解变成O(n)。
你可以使用strbuilder.insert(0,i);
也许我错过了一些东西,但你想结束一个看起来像这样的字符串,"999897969594...543210"
,对吗?
StringBuilder sb = new StringBuilder();
for(int i=99;i>=0;i--){
sb.append(String.valueOf(i));
}
作为替代解决方案,您可以使用LIFO结构(如堆栈)来存储所有字符串,并在完成后将它们全部取出并将它们放入StringBuilder中。它自然地反转放置在其中的项目(字符串)的顺序。
Stack<String> textStack = new Stack<String>();
// push the strings to the stack
while(!isReadingTextDone()) {
String text = readText();
textStack.push(text);
}
// pop the strings and add to the text builder
String builder = new StringBuilder();
while (!textStack.empty()) {
builder.append(textStack.pop());
}
// get the final string
String finalText = builder.toString();
这个线程很老了,但你也可以想一下递归StringBuilder的递归解决方案。这允许防止任何反向处理等。只需要通过递归设计迭代并仔细决定退出条件。
public class Test {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
doRecursive(sb, 100, 0);
System.out.println(sb.toString());
}
public static void doRecursive(StringBuilder sb, int limit, int index) {
if (index < limit) {
doRecursive(sb, limit, index + 1);
sb.append(Integer.toString(index));
}
}
}
当我偶然发现这篇文章时,我有类似的要求。我想要一种快速的方法来构建一个可以从双方增长的字符串,即。在正面和背面任意添加新字母。我知道这是一篇很老的帖子,但它激发了我尝试创建字符串的几种方法,我想我会分享我的发现。我也在使用一些Java 8构造,它可以优化案例4和5的速度。
https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e6420
上面的要点有详细的代码,任何人都可以运行。我在这方面采取了几种方法来增长; 1)附加到StringBuilder,2)插入StringBuilder的前面,如@Mehrdad所示,3)从StringBuilder的前面和末尾部分插入,4)使用列表从末尾追加,5)使用Deque来从前面追加。
// Case 2
StringBuilder build3 = new StringBuilder();
IntStream.range(0, MAX_STR)
.sequential()
.forEach(i -> {
if (i%2 == 0) build3.append(Integer.toString(i)); else build3.insert(0, Integer.toString(i));
});
String build3Out = build3.toString();
//Case 5
Deque<String> deque = new ArrayDeque<>();
IntStream.range(0, MAX_STR)
.sequential()
.forEach(i -> {
if (i%2 == 0) deque.addLast(Integer.toString(i)); else deque.addFirst(Integer.toString(i));
});
String dequeOut = deque.stream().collect(Collectors.joining(""));
我将专注于前面附加的情况,即。情况2和案例5. StringBuilder的实现在内部决定内部缓冲区如何增长,除了在前端附加限制速度的情况下从左到右移动所有缓冲区。直接插入StringBuilder前面所花费的时间增长到非常高的值,如@Mehrdad所示,如果需要只有长度小于90k字符的字符串(仍然很多),前插入将构建一个String,同时通过在末尾附加来构建相同长度的String。我所说的是时间惩罚确实会被踢出并且是巨大的,但只有当你必须构建非常庞大的字符串时。可以使用双端队列并在末尾连接字符串,如我的示例所示。但是StringBuilder的读取和编码更直观,对于较小的字符串,惩罚也无关紧要。
实际上,案例2的表现要比案例1快得多,我似乎并不理解。我假设StringBuilder中内部缓冲区的增长在前加法和后加法的情况下是相同的。我甚至将最小堆设置为非常大的数量,以避免延迟堆增长,如果这会起到作用。也许有更好理解的人可以在下面评论。
以上是关于java:使用StringBuilder在开头插入的主要内容,如果未能解决你的问题,请参考以下文章
java基础知识四 math类 字符 字符串 控制台输入输出 StringBuilder与StringBuffer