जावा: शुरुआत में डालने के लिए StringBuilder का उपयोग करें


94

मैं केवल स्ट्रिंग के साथ ऐसा कर सकता था, उदाहरण के लिए:

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

क्या स्ट्रींगबर्ल के साथ इसे हासिल करने का कोई तरीका है? धन्यवाद।

जवाबों:


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

चेतावनी: यह के उद्देश्य को हरा देता हैStringBuilder , लेकिन यह वही करता है जो आपने पूछा था।


बेहतर तकनीक (हालांकि अभी भी आदर्श नहीं है):

  1. रिवर्स प्रत्येक स्ट्रिंग आप सम्मिलित करना चाहते।
  2. प्रत्येक स्ट्रिंग को एक में जोड़ेंStringBuilder
  3. पूरा StringBuilder होने पर उल्टा कर दें ।

यह O ( n ) में O ( n () विलयन को बदल देगा ।


2
... चूँकि यह AbstractStringBuilderसम्मिलित किए गए सभी अनुक्रमों को सम्मिलित करता है, जो सम्मिलित किए गए लोगों के लिए कमरा ढूंढने के लिए सम्मिलित करता है। हालांकि, यह एक कार्यान्वयन विवरण है, सिद्धांत का नहीं।
एंटोनियो

1
@entonio: वास्तव में, लेकिन यह बहुत महत्वपूर्ण विवरण है। :)
उपयोगकर्ता ५४१६ --६

1
मैं देख रहा हूँ, ऐसा लगता है कि मुझे StringBuilder का उपयोग नहीं करना चाहिए, बहुत बहुत धन्यवाद
user685275

@ user685275: हाँ, यदि आपको पीछे की ओर प्रविष्टि की आवश्यकता है, तो आपको वास्तव में कुछ ऐसा चाहिए जो स्ट्रिंग की शुरुआत में सम्मिलित हो सके। मुझे लगता है कि सबसे आसान समाधान ऊपर की तकनीक है (दो बार चीजों को उलट देना), हालांकि आप शायद चार सरणियों के साथ अपनी खुद की एक बेहतर कक्षा बना सकते हैं ("deque" में देखना चाहते हैं)।
user541686

1
@rogerdpack: मैं कहूंगा कि यह तंत्र है, उद्देश्य नहीं। उद्देश्य स्ट्रिंग हेरफेर की तुलना में asymptotically तेज होना है, जो कि यह नहीं होगा यदि आप इसे गलत उपयोग करते हैं।
user541686

31

आप उपयोग कर सकते हैं strbuilder.insert(0,i);


2
इसे इतने लाइक क्यों मिले! वर्ग को सही ढंग से परिभाषित नहीं किया गया है - केवल विधि कॉल के हस्ताक्षर!
JGFMK

13

शायद मुझे कुछ याद आ रहा है, लेकिन आप एक स्ट्रिंग के साथ हवा देना चाहते हैं जो इस तरह दिखता है "999897969594...543210", सही है?

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

लूप के चतुर हेरफेर द्वारा समाधान प्रदान करते हुए इस पोस्ट को ज्यादा मतदान नहीं मिला,
नामित-मोन-आईआर

1
@ नोम-मोन-इर वह सिर्फ स्ट्रिंग को उलट रहा है। यह उत्तर नहीं देता कि बाईं ओर कैसे जोड़ा जाए।
रेमंड चेनन

वांछित प्रभाव प्राप्त करता है।
स्पेक

मुझे लगता है कि ऐसे मामले हो सकते हैं जिनमें आप इस दृष्टिकोण का उपयोग करने के बजाय शुरुआत में सम्मिलित करने के लिए हैक करने की कोशिश कर सकते हैं जो स्ट्रिंगबर्ल की वास्तविक क्षमता का उपयोग करता है। वैसे भी, ऐसे मामले हैं जिनमें आप पाश को उलट नहीं सकते हैं, इसलिए आपको अन्य उत्तरों की भी आवश्यकता है।
फोनिक्स

7

एक वैकल्पिक समाधान के रूप में आप सभी स्ट्रिंग्स को स्टोर करने के लिए एक LIFO संरचना (एक स्टैक की तरह) का उपयोग कर सकते हैं और जब आप किया जाता है तो बस उन सभी को बाहर निकालकर उन्हें स्ट्रिंगबर्ल में डाल दें। यह स्वाभाविक रूप से इसमें रखी वस्तुओं (तार) के क्रम को उलट देता है।

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

4
ArrayDeque के बजाय उपयोग किया जाना चाहिए Stack । "LIFO स्टैक ऑपरेशन्स का अधिक पूर्ण और सुसंगत सेट {@link Deque} इंटरफेस और इसके कार्यान्वयन द्वारा प्रदान किया जाता है, जिसे इस वर्ग के लिए प्राथमिकता में उपयोग किया जाना चाहिए।"
Luna

5

यह धागा काफी पुराना है, लेकिन आप इसे भरने के लिए स्ट्रिंगबर्ल से गुजरने वाले पुनरावर्ती समाधान के बारे में भी सोच सकते हैं। यह किसी भी रिवर्स प्रोसेसिंग आदि को रोकने की अनुमति देता है। बस एक पुनरावृत्ति के साथ अपने पुनरावृत्ति को डिजाइन करने और एक निकास स्थिति के लिए सावधानीपूर्वक निर्णय लेने की आवश्यकता है।

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));
        }
    }
}

3

जब मुझे इस पद पर ठोकर लगी तो मुझे भी ऐसी ही आवश्यकता थी। मैं एक तेजी से रास्ता बनाना चाहता था एक स्ट्रिंग जो दोनों तरफ से बढ़ सके। नए अक्षरों को सामने के साथ-साथ मनमाने ढंग से जोड़ें। मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन इसने मुझे स्ट्रिंग्स बनाने के कुछ तरीकों की कोशिश करने के लिए प्रेरित किया और मुझे लगा कि मैं अपने निष्कर्षों को साझा करूंगा। मैं इसमें कुछ जावा 8 निर्माणों का भी उपयोग कर रहा हूं, जो 4 और 5 मामलों में गति को अनुकूलित कर सकते थे।

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

ऊपर दिए गए Gist में विस्तृत कोड है जिसे कोई भी चला सकता है। मैंने इसमें बढ़ते तारों के कुछ तरीके निकाले; 1) स्ट्रींगबर्ल के लिए आवेदन करें, 2) स्ट्रींगबर्ल के सामने डालें जैसा कि @ मेहरदाद द्वारा दिखाया गया है, 3) आंशिक रूप से सामने से और साथ ही स्ट्रिंगबर्ल के अंत में डालें, 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 के सामने सीधे डालने पर समय लगता है, तो वास्तव में उच्च मूल्यों तक बढ़ता है, जैसा कि @ मेहरदाद द्वारा दिखाया गया है, अगर जरूरत केवल 90k वर्ण (जो अभी भी बहुत कम है) से कम लंबाई के तारों की है, तो सामने सम्मिलित होगा एक ही समय में एक स्ट्रिंग बनाने के रूप में यह अंत में जोड़कर एक ही लंबाई के एक स्ट्रिंग का निर्माण करने के लिए ले जाएगा। मैं जो कह रहा हूं वह यह है कि टाइम पेनल्टी वास्तव में किक करती है और विशाल होती है, लेकिन केवल तब जब आपको वास्तव में बहुत बड़े तार बनाने हों। एक उदाहरण के रूप में एक चित्र का उपयोग कर सकते हैं और अंत में तार में शामिल हो सकते हैं।

वास्तव में केस 2 का प्रदर्शन केस 1 की तुलना में बहुत तेज है, जिसे मैं समझ नहीं पा रहा हूं। मैं मानता हूं कि स्ट्रांगबर्ल में आंतरिक बफर के लिए विकास आगे के एपेंड और बैक अपेंड के मामले में समान होगा। मैं भी ढेर वृद्धि में देरी से बचने के लिए एक बहुत बड़ी राशि के लिए न्यूनतम ढेर सेट, अगर वह एक भूमिका निभाई होती। हो सकता है कि बेहतर समझ रखने वाला कोई व्यक्ति नीचे टिप्पणी कर सकता है।


1
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

1
Stackoverflow में आपका स्वागत है। कृपया इस बात का स्पष्टीकरण शामिल करें कि कोड क्या करता है और यह प्रश्न में समस्या को कैसे हल करता है।
bad_coder

1

आप ऑफसेट के साथ सम्मिलित विधि का उपयोग कर सकते हैं। जैसा कि '0' पर सेट ऑफ़सेट का मतलब है कि आप अपने स्ट्रिंगबुलस्ट के सामने वाले हिस्से को जोड़ रहे हैं।

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

नोट : डालने की विधि के रूप में सभी प्रकार की आदिम स्वीकार करते हैं, आप int, long, char [] आदि के लिए उपयोग कर सकते हैं।


0

कैसा रहेगा:

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

लेकिन इसके साथ, आप ओ (एन) के बजाय ऑपरेशन ओ (एन ^ 2) कर रहे हैं।

जावा डॉक्स से स्निपेट:

इस वर्ण अनुक्रम में ऑब्जेक्ट तर्क के स्ट्रिंग प्रतिनिधित्व को सम्मिलित करता है। समग्र प्रभाव ठीक उसी तरह है जैसे कि दूसरे तर्क को विधि द्वारा एक स्ट्रिंग में बदल दिया गया था String.valueOf(Object), और उस स्ट्रिंग के वर्णों को संकेतित ऑफसेट पर इस वर्ण अनुक्रम में डाला गया था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.