6 ответов:
StringBuilder sb = new StringBuilder(); for(int i=0;i<100;i++){ sb.insert(0, Integer.toString(i)); }предупреждение:он побеждает цель
StringBuilder, но он делает то, что вы просили.
лучше техника (хотя все еще не идеально):
- реверс каждого строку, которую вы хотите вставить.
- добавить каждую строку
StringBuilder.- реверс весь
StringBuilderкогда вы закончите.это превратит O (n2) решение в O (n).
может быть, я что-то упускаю, но вы хотите закончить строку, которая выглядит так,
"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)); } } }
У меня было аналогичное требование, когда я наткнулся на этот пост. Я хотел быстрый способ построить строку, которая может расти с обеих сторон ie. добавляйте новые буквы как спереди, так и сзади произвольно. Я знаю, это старый пост, но он вдохновил меня попробовать несколько способов создания строк и я решила поделиться своими находками. Я также использую некоторые конструкции Java 8 в этом, которые могли бы оптимизировать скорость в случаях 4 и 5.
https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e6420
суть выше имеет подробный код, который любой может запустить. Я взял несколько способов выращивания строк в этом; 1) добавить к StringBuilder, 2) вставка в передней части класса StringBuilder, как показано на @Мехрдад, 3) частично вставкой спереди, а также конец класса StringBuilder, 4), используя список добавить с конца, 5) с помощью двухсторонней очереди, чтобы добавлять с фронта.
// 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(""));я сосредоточусь на фронт добавляет только случаи ie. случай 2 и случай 5. Реализация StringBuilder внутренне решает, как внутренний буфер растет, что помимо перемещения всего буфера слева направо в случае переднего добавления ограничивает скорость. В то время как время, затраченное при вставке непосредственно в переднюю часть StringBuilder, растет до действительно высоких значений, как показано @Mehrdad, если нужно иметь только строки длиной менее 90k символов (что все еще много), передняя вставка построит строку в том же самом время, необходимое для построения строки одинаковой длины путем добавления в конце. То, что я говорю, это то, что время время штраф действительно пинает и огромно, но только тогда, когда вы должны построить действительно огромные строки. Можно было бы использовать deque и присоединиться к строкам в конце, как показано в моем примере. Но StringBuilder немного более интуитивно понятен для чтения и кода, и штраф не будет иметь значения для меньших строк.
на самом деле производительность для случая 2 намного быстрее, чем Случай 1, который я не кажусь взять в толк. Я предполагаю, что рост для внутреннего буфера в StringBuilder будет одинаковым в случае переднего добавления и заднего добавления. Я даже установил минимальную кучу на очень большое количество, чтобы избежать задержки в росте кучи, если бы это сыграло роль. Возможно, кто-то, у кого есть лучшее понимание, может прокомментировать ниже.
Comments