programing

java: String Builder를 사용하여 선두에 삽입

sourcetip 2022. 11. 26. 13:50
반응형

java: String Builder를 사용하여 선두에 삽입

이 작업은 String에서만 수행할 수 있습니다.다음은 예를 제시하겠습니다.

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

String Builder를 사용하여 이를 실현하는 방법이 있습니까?감사해요.

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

경고:의 목적은 어긋나지만, 요구하신 대로 됩니다.


나은 기술(이상적이지는 않지만):

  1. 삽입할 각 문자열을 반대로 바꿉니다.
  2. 각 문자열을 추가합니다.StringBuilder.
  3. 전체를 반전시키다 StringBuilder할 수 있어요.

그러면 O() 용액이 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));
        }
    }
}

제가 이 게시물을 접했을 때도 비슷한 요구 사항이 있었습니다.양쪽에서 성장 가능한 String을 빠르게 만들고 싶었습니다.즉, 앞면과 뒷면에 임의로 새로운 글자를 추가해 주세요.오래된 포스트라는 건 알지만, 이 포스트를 보고 몇 가지 방법을 시도해 보고 결과를 공유하려고 합니다.또, 케이스 4와 케이스 5에서는 속도를 최적화할 수 있는 Java 8 구조도 몇개 사용하고 있습니다.

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

위의 Gist에는 누구나 실행할 수 있는 상세 코드가 있습니다.여기서 스트링을 키우는 방법은 몇 가지 있습니다. 1) String Builder에 추가 2) String Builder 전면에 삽입(@Mehrdad), 3) String Builder의 전면과 끝에서 부분적으로 삽입, 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)에만 초점을 맞춥니다.String Builder의 구현은 내부 버퍼의 확장 방법을 결정합니다.이는 전면 추가 시 모든 버퍼를 좌우로 이동하는 것과 별개입니다.String Builder의 전면에 직접 삽입할 때 걸리는 시간은 @Mehrdad에서 알 수 있듯이 매우 높은 값으로 증가하지만 90k자 미만의 문자열(아직도 많은 문자열)만을 필요로 하는 경우 전면 삽입은 스트링을 추가함으로써 동일한 길이의 문자열을 작성하는 것과 동시에 스트링을 구축합니다.끝. 시간 벌칙은 정말 대단하지만 정말 큰 끈을 만들어야 할 때에만 유효하다는 거죠.이 예에서 보듯이 디큐를 사용하여 마지막에 줄을 연결할 수 있습니다.그러나 String Builder는 읽고 코드화하는 것이 조금 더 직관적이기 때문에 작은 문자열에 대한 패널티는 문제가 되지 않습니다.

사실 케이스2의 퍼포먼스가 케이스1보다 훨씬 빠른데 이해가 안 되네요.String Builder의 내부 버퍼 증가는 전면 추가와 후면 추가의 경우 동일할 것으로 예상됩니다.히프 증가의 지연을 피하기 위해 최소 힙을 매우 큰 양으로 설정했습니다.이해력이 더 있는 사람이 아래에 코멘트를 할 수 있을지도 모릅니다.

오프셋을 '0'으로 설정한 경우 삽입 방법을 사용할 수 있습니다.오프셋은 StringBuilder의 전면에 추가하는 것을 의미합니다.

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

메모: 삽입 메서드는 모든 유형의 프리미티브를 지원하므로 int, long, char[] 등에 사용할 수 있습니다.

Difference Between String, StringBuilder And StringBuffer Classes
String
String is immutable ( once created can not be changed )object. The object created as a
String is stored in the Constant String Pool.
Every immutable object in Java is thread-safe, which implies String is also thread-safe. String
can not be used by two threads simultaneously.
String once assigned can not be changed.
StringBuffer
StringBuffer is mutable means one can change the value of the object. The object created
through StringBuffer is stored in the heap. StringBuffer has the same methods as the
StringBuilder , but each method in StringBuffer is synchronized that is StringBuffer is thread
safe .
Due to this, it does not allow two threads to simultaneously access the same method. Each
method can be accessed by one thread at a time.
But being thread-safe has disadvantages too as the performance of the StringBuffer hits due
to thread-safe property. Thus StringBuilder is faster than the StringBuffer when calling the
same methods of each class.
String Buffer can be converted to the string by using
toString() method.

    StringBuffer demo1 = new StringBuffer("Hello") ;

// The above object stored in heap and its value can be changed.
/
// Above statement is right as it modifies the value which is allowed in the StringBuffer
StringBuilder
StringBuilder is the same as the StringBuffer, that is it stores the object in heap and it can also
be modified. The main difference between the StringBuffer and StringBuilder is
that StringBuilder is also not thread-safe.
StringBuilder is fast as it is not thread-safe.
/
// The above object is stored in the heap and its value can be modified
/
// Above statement is right as it modifies the value which is allowed in the StringBuilder

그럼 어떻게 해?

StringBuilder builder = new StringBuilder();
for(int i=99;i>=0;i--){
    builder.append(Integer.toString(i));
}
builder.toString();

또는

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

그러나 이것으로 O(N)가 아닌 O(N^2) 연산을 합니다.

Java 문서의 일부:

Object 인수의 문자열 표현을 이 문자 시퀀스에 삽입합니다.는 두 .String.valueOf(Object)그리고 그 문자열의 문자가 지정된 오프셋으로 이 문자 시퀀스에 삽입되었습니다.

언급URL : https://stackoverflow.com/questions/5931261/java-use-stringbuilder-to-insert-at-the-beginning

반응형