2011-05-09 2 views

답변

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

경고 : StringBuilder의 목적을 패배,하지만 당신이 무엇을 요구하지. (비록 여전히 좋지 않은)


더 나은 기술 :

  1. 삽입 할 각 문자열입니다.
  2. 각 문자열을 StringBuilder에 붙입니다.
  3. 완료하면 전체를StringBuilder 번으로 반대로 바꿉니다. O로

이것이 O을 설정한다 (N ²) 용액 (N).

+0

... 'AbstractStringBuilder'가 삽입 된 색인을위한 공간을 찾기 위해 삽입 색인을 지나서 모든 내용을 이동하게하기 때문에. 그러나 이는 구현 세부 사항으로 원칙 중 하나가 아닙니다. – entonio

+1

@entonio : 실제로, 그러나 그것은 매우 비판적입니다. :) – Mehrdad

+1

그래, 내가 StringBuilder를 사용해서는 안된다. 고마워. – user685275

18

당신은

7

strbuilder.insert(0,i);가 어쩌면 내가 모르는 뭔가가있어 사용할 수 있지만이 같은 "999897969594...", 올바른 보이는 문자열로 바람 싶어?

StringBuilder sb = new StringBuilder(); 
for(int i=99;i>=0;i--){ 
    sb.append(String.valueOf(i)); 
} 
+0

이상하게도이 게시물은 루프를 영리하게 조작하여 솔루션을 제공하는 동안 투표를 많이받지 못했습니다. –

+1

@ nom-mon-ir 그는 단지 문자열을 뒤집습니다. 왼쪽에 추가하는 방법에 대한 대답은 아닙니다. –

+0

원하는 효과를냅니다. – Speck

3

이 스레드는 꽤 오래되었지만 StringBuilder를 채우는 재귀 적 솔루션에 대해서도 생각해 볼 수 있습니다. 역순 처리를 막을 수 있습니다. 재귀를 사용하여 반복을 설계하고 종료 조건을주의 깊게 결정해야합니다. 당신은 모든 문자열을 저장하기 위해 (스택 같은)는 LIFO 구조를 사용하고 완료되면 단지 그들 모두를 꺼내 모두 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)); 
     } 
    } 
} 
6

. 그것은 자연스럽게 그것에 배치 된 항목 (문자열)의 순서를 바꿉니다.

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(); 
+3

'Stack' 대신'ArrayDeque'을 사용해야합니다. "LIFO 스택 조작의보다 완전하고 일관된 세트는, Deek 인터페이스 및 그 구현에 의해 제공됩니다.이 인터페이스는이 클래스보다 우선적으로 사용되어야합니다. –

0

내가이 게시물을 발견했을 때 비슷한 요구 사항이있었습니다. 즉 양쪽에서 성장할 수있는 String을 만드는 빠른 방법을 원했습니다. 정면에 새로운 문자를 추가하거나 임의로 되돌릴 수 있습니다. 나는 이것이 오래된 글이라는 것을 알고 있지만, 그것은 내가 문자열을 만드는 몇 가지 방법을 시험해보고 영감을 주었고, 나는 나의 발견을 공유 할 것이라고 생각했다. 또한 일부 Java 8가지 경우 4에서 속도를 최적화 한 수이의 구조 및 5

https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e6420

요점은 위의 사람이 실행할 수있는 세부적인 코드가 사용하고 있습니다. 나는 이것에서 문자열을 늘리는 데 몇 가지 방법을 사용했습니다. 1) StringBuilder에 추가, 2) @Mehrdad에서와 같이 StringBuilder 앞에 삽입, 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("")); 

전 추가에만 초점을 맞 춥니 다. case 2 및 case 5를 사용합니다. StringBuilder 구현은 내부 버퍼가 어떻게 커지는지를 결정합니다. 앞쪽 추가시 모든 버퍼를 왼쪽에서 오른쪽으로 이동하는 것 외에 속도가 제한됩니다. @Mehrdad에 표시된 것처럼 StringBuilder의 전면에 직접 삽입하는 데 걸리는 시간이 @Mehrdad에 표시된 것처럼 매우 높아지지만 길이가 90k 미만인 문자열 (여전히 많은 양)을 필요로하는 경우 앞에 삽입하면 마지막에 추가하여 동일한 길이의 String을 작성하는 것과 동일한 시간에 String을 작성하십시오. 제가 말하고있는 것은 시간의 벌칙이 실제로 일어나고 거대하지만, 정말로 거대한 문자열을 만들어야 만 할 때입니다. 내 예제와 같이 끝에 deque를 사용하여 문자열을 결합 할 수 있습니다. 그러나 StringBuilder는 읽기 쉽고 코드화하기에 좀 더 직관적이며, 작은 문자열에 대해서는 페널티가 중요하지 않습니다.

사실 케이스 2의 성능은 사례 1보다 훨씬 빠르며 이해가되지 않습니다. StringBuilder의 내부 버퍼의 증가가 앞쪽 추가 및 뒤쪽 추가의 경우 동일하다고 가정합니다. heap 성장이 지연되는 것을 피하기 위해 최소한의 힙을 매우 큰 양으로 설정했습니다. 어쩌면 더 나은 이해를 가진 사람이 아래에 논평 할 수 있습니다.

관련 문제