Java: используйте StringBuilder для вставки в начале

Я мог сделать это только со строкой, например:

String str="";
for(int i=0;i<100;i++){
    str=i+str;
}

Есть ли способ добиться этого с помощью StringBuilder? Спасибо.

67 голосов | спросил user685275 9 Mayam11 2011, 04:08:49

6 ответов


0
StringBuilder sb = new StringBuilder();
for(int i=0;i<100;i++){
    sb.insert(0, Integer.toString(i));
}

Предупреждение что ты спросил.


Лучшая техника (хотя все еще не идеальная):

  1. Отмените каждую строку, которую хотите вставить.
  2. Добавить каждую строку в StringBuilder.
  3. Отмените весь StringBuilder, когда вы закончите.

Это превратит решение O ( n ²) в O ( n ).

ответил Mehrdad 9 Mayam11 2011, 04:10:39
0

вы можете использовать strbuilder.insert(0,i);

ответил ratchet freak 9 Mayam11 2011, 04:11:39
0

Может быть, я что-то упускаю, но вы хотите получить строку, которая выглядит следующим образом, "999897969594...543210", правильно?

StringBuilder sb = new StringBuilder();
for(int i=99;i>=0;i--){
    sb.append(String.valueOf(i));
}
ответил Speck 9 Mayam11 2011, 08:27:38
0

В качестве альтернативного решения вы можете использовать структуру 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();
ответил Vasile Jureschi 8 Jam1000000amThu, 08 Jan 2015 10:13:01 +030015 2015, 10:13:01
0

Этот поток довольно старый, но вы также можете подумать о рекурсивном решении, передающем 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));
        }
    }
}
ответил Benjamin 4 Jpm1000000pmSat, 04 Jan 2014 18:01:28 +040014 2014, 18:01:28
0

У меня было похожее требование, когда я наткнулся на этот пост. Я хотел быстрый способ построить строку, которая может расти с обеих сторон, т.е. добавить новые буквы на передней и задней части произвольно. Я знаю, что это старый пост, но он вдохновил меня попробовать несколько способов создания строк, и я решил поделиться своими выводами. Я также использую некоторые конструкции Java 8, которые могли бы оптимизировать скорость в случаях 4 и 5.

https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf/66> pp

Gist выше содержит подробный код, который может запустить каждый. Я взял несколько способов выращивания строк в этом; 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, если нужно, чтобы строки длиной не превышали 90 тыс. Символов (что по-прежнему много), передняя вставка будет построить строку в то же время, что и для создания строки такой же длины, добавив в конце. То, что я говорю, это то, что временное наказание действительно пинает и огромно, но только тогда, когда вам нужно построить действительно огромные строки. Можно использовать деку и соединить строки в конце, как показано в моем примере. Но StringBuilder более интуитивно понятен для чтения и кодирования, и штраф не будет иметь значения для небольших строк.

На самом деле производительность для случая 2 намного выше, чем для случая 1, что мне кажется не понятным. Я предполагаю, что рост внутреннего буфера в StringBuilder будет одинаковым в случае фронтального и обратного добавления. Я даже установил минимальную кучу на очень большую величину, чтобы избежать задержки роста кучи, если бы это сыграло свою роль. Может быть, кто-то, кто лучше понимает, может прокомментировать ниже.

ответил Siddharth Wagle 30 SatEurope/Moscow2017-12-30T20:13:24+03:00Europe/Moscow12bEurope/MoscowSat, 30 Dec 2017 20:13:24 +0300 2017, 20:13:24

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132