सी # या जावा: स्ट्रिंग स्ट्रिंग के साथ प्रीपेंड करें?


102

मुझे पता है कि हम स्ट्रिंग्स को इस्तेमाल कर सकते हैं StringBuilder। क्या कोई ऐसा तरीका है जिससे हम स्ट्रिंग्स को प्रीपेंड कर सकते हैं (यानी स्ट्रिंग के सामने तार जोड़ StringBuilderसकते हैं ) ताकि हम प्रदर्शन के लाभ StringBuilderप्रदान कर सकें ?


मुझे आपका प्रश्न समझ में नहीं आता है
मौरिस पेरी

5
प्रारंभ में लगा। शब्द प्रीपेंड है। मेरा मानना ​​है कि एक स्ट्रिंग को एक ही बार में स्ट्रिंग के दोनों सिरों पर जोड़ने जैसा कुछ होना चाहिए?
जोएल म्यूलर

जवाबों:


164

डालने की विधि का उपयोग करते हुए 0 से सेट स्थिति पैरामीटर के साथ प्रीपेंडिंग (यानी शुरुआत में डालने) के समान होगा।

एक उदाहरण है: varStringBuilder.insert(0, "someThing");

यह C # और Java दोनों के लिए काम करता है


7
StringBuilder डालने जावा के लिए: java.sun.com/j2se/1.5.0/docs/api/java/lang/…
मैथ्यू Farwell

: प्रासंगिक एपीआई के लिए सही JavaDoc है docs.oracle.com/javase/1.5.0/docs/api/java/lang/...
स्लेज

29

स्ट्रीपिंग को रोकना आमतौर पर बैकिंग ऐरे में कुछ डालने के बाद सब कुछ कॉपी करने की आवश्यकता होती है, इसलिए यह अंत में लागू करने के रूप में जल्दी नहीं होगा।

लेकिन आप इसे जावा में इस तरह से कर सकते हैं (सी # में यह समान है, लेकिन विधि कहा जाता है Insert):

aStringBuilder.insert(0, "newText");

11

यदि आपको बहुत सारे प्रीपेंड के साथ उच्च प्रदर्शन की आवश्यकता है, तो आपको अपना स्वयं का संस्करण लिखना होगा StringBuilder(या किसी और का उपयोग करना होगा)। मानक के साथ StringBuilder(हालांकि तकनीकी रूप से इसे अलग तरीके से लागू किया जा सकता है) सम्मिलन बिंदु के बाद सम्मिलित डेटा की प्रतिलिपि बनाने की आवश्यकता होती है। पाठ का n टुकड़ा डालने में O (n ^ 2) समय लग सकता है।

एक भोली दृष्टिकोण बैकिंग char[]बफर के साथ-साथ लंबाई में एक ऑफसेट जोड़ना होगा । जब एक प्रीपेंड के लिए पर्याप्त जगह नहीं है, तो डेटा को अधिक से अधिक स्थानांतरित करना कड़ाई से आवश्यक है। यह ओ (एन लॉग एन) (मुझे लगता है) के नीचे प्रदर्शन वापस ला सकता है। बफर चक्रीय बनाने के लिए एक अधिक परिष्कृत दृष्टिकोण है। इस तरह से सरणी के दोनों सिरों पर अतिरिक्त स्थान सन्निहित हो जाता है।


5

आप एक एक्सटेंशन विधि आज़मा सकते हैं:

/// <summary>
/// kind of a dopey little one-off for StringBuffer, but 
/// an example where you can get crazy with extension methods
/// </summary>
public static void Prepend(this StringBuilder sb, string s)
{
    sb.Insert(0, s);
}

StringBuilder sb = new StringBuilder("World!");
sb.Prepend("Hello "); // Hello World!

5

आप स्ट्रिंग को उल्टा बना सकते हैं और फिर परिणाम को उल्टा कर सकते हैं। आप O (n ^ 2) सबसे खराब स्थिति लागत के बजाय O (n) लागत का उपयोग करते हैं।


2
यह तभी काम करता है जब आप व्यक्तिगत पात्रों को जोड़ रहे हों। अन्यथा आपको प्रत्येक स्ट्रिंग को उल्टा करने की आवश्यकता होगी जिसे आप जोड़ते हैं जो सबसे अधिक खाएगा यदि बचत बचत के आकार और संख्या के आधार पर नहीं होती है।
स्लेज

4

मैंने इसका उपयोग नहीं किया है, लेकिन जावा के लिए रस्सियों को पेचीदा लगता है। परियोजना का नाम शब्दों पर एक नाटक है, गंभीर काम के लिए एक स्ट्रिंग के बजाय एक रस्सी का उपयोग करें । प्रीपेडिंग और अन्य कार्यों के लिए प्रदर्शन दंड के आसपास हो जाता है। एक नज़र के लायक है, अगर आप ऐसा करने जा रहे हैं।

रस्सी स्ट्रिंग्स के लिए एक उच्च प्रदर्शन प्रतिस्थापन है। "रोप्स: अ अल्टरनेटिव टू स्ट्रिंग्स" में विस्तार से वर्णित डेटास्ट्रक्चर, स्ट्रिप और स्ट्रिंगरबफ़र दोनों की तुलना में समान रूप से बेहतर प्रदर्शन प्रदान करता है, जैसे कि सामान्य स्ट्रिंग संशोधनों जैसे कि प्रीपेंड, ऐपेंड, डिलीट और इंसर्ट। स्ट्रिंग्स की तरह, रस्सियां ​​अपरिवर्तनीय हैं और इसलिए बहु-थ्रेडेड प्रोग्रामिंग में उपयोग के लिए अच्छी तरह से अनुकूल हैं।


4

यहाँ आप क्या कर सकते हैं यदि आप Java के StringBuilder वर्ग का उपयोग करना चाहते हैं:

StringBuilder str = new StringBuilder();
str.Insert(0, "text");

3

अगर मैं आपको सही तरीके से समझता हूं, तो डालने का तरीका ऐसा लगता है जैसे यह वही करेगा जो आप चाहते हैं। बस ऑफसेट 0 पर स्ट्रिंग डालें।



2

अन्य टिप्पणियों से देखते हुए, ऐसा करने का कोई मानक त्वरित तरीका नहीं है। StringBuilder का उपयोग करना .Insert(0, "text")लगभग 1-3x जितना तेज़ होता है, उतनी ही तेजी से दर्दनाक धीमी गति से कंक्रीटिंग (> 10000 कंसर्ट के आधार पर) का उपयोग करता है, इसलिए नीचे संभावित रूप से हज़ारों गुना तेज गति करने के लिए एक वर्ग है!

मैंने कुछ अन्य बुनियादी कार्यक्षमता जैसे कि append(), subString()और length()आदि को शामिल किया है और दोनों स्ट्रीपबर्ल अपेंडिक्स की तुलना में लगभग दो गुना तेजी से 3x धीमी गति से भिन्न होते हैं। StringBuilder की तरह, इस वर्ग में बफर स्वचालित रूप से बढ़ जाएगा जब पाठ पुराने बफर आकार को ओवरफ्लो करता है।

कोड का काफी परीक्षण किया गया है, लेकिन मैं इसे बग से मुक्त होने की गारंटी नहीं दे सकता।

class Prepender
{
    private char[] c;
    private int growMultiplier;
    public int bufferSize;      // Make public for bug testing
    public int left;            // Make public for bug testing
    public int right;           // Make public for bug testing
    public Prepender(int initialBuffer = 1000, int growMultiplier = 10)
    {
        c = new char[initialBuffer];
        //for (int n = 0; n < initialBuffer; n++) cc[n] = '.';  // For debugging purposes (used fixed width font for testing)
        left = initialBuffer / 2;
        right = initialBuffer / 2;
        bufferSize = initialBuffer;
        this.growMultiplier = growMultiplier;
    }
    public void clear()
    {
        left = bufferSize / 2;
        right = bufferSize / 2;
    }
    public int length()
    {
        return right - left;
    }

    private void increaseBuffer()
    {
        int nudge = -bufferSize / 2;
        bufferSize *= growMultiplier;
        nudge += bufferSize / 2;
        char[] tmp = new char[bufferSize];
        for (int n = left; n < right; n++) tmp[n + nudge] = c[n];
        left += nudge;
        right += nudge;
        c = new char[bufferSize];
        //for (int n = 0; n < buffer; n++) cc[n]='.';   // For debugging purposes (used fixed width font for testing)
        for (int n = left; n < right; n++) c[n] = tmp[n];
    }

    public void append(string s)
    {
        // If necessary, increase buffer size by growMultiplier
        while (right + s.Length > bufferSize) increaseBuffer();

        // Append user input to buffer
        int len = s.Length;
        for (int n = 0; n < len; n++)
        {
            c[right] = s[n];
            right++;
        }
    }
    public void prepend(string s)
    {
        // If necessary, increase buffer size by growMultiplier
        while (left - s.Length < 0) increaseBuffer();               

        // Prepend user input to buffer
        int len = s.Length - 1;
        for (int n = len; n > -1; n--)
        {
            left--;
            c[left] = s[n];
        }
    }
    public void truncate(int start, int finish)
    {
        if (start < 0) throw new Exception("Truncation error: Start < 0");
        if (left + finish > right) throw new Exception("Truncation error: Finish > string length");
        if (finish < start) throw new Exception("Truncation error: Finish < start");

        //MessageBox.Show(left + " " + right);

        right = left + finish;
        left = left + start;
    }
    public string subString(int start, int finish)
    {
        if (start < 0) throw new Exception("Substring error: Start < 0");
        if (left + finish > right) throw new Exception("Substring error: Finish > string length");
        if (finish < start) throw new Exception("Substring error: Finish < start");
        return toString(start,finish);
    }

    public override string ToString()
    {
        return new string(c, left, right - left);
        //return new string(cc, 0, buffer);     // For debugging purposes (used fixed width font for testing)
    }
    private string toString(int start, int finish)
    {
        return new string(c, left+start, finish-start );
        //return new string(cc, 0, buffer);     // For debugging purposes (used fixed width font for testing)
    }
}

1

आप एक साधारण वर्ग के साथ स्वयं स्ट्रिंगबर्ल के लिए एक एक्सटेंशन बना सकते हैं:

namespace Application.Code.Helpers
{
    public static class StringBuilderExtensions
    {
        #region Methods

        public static void Prepend(this StringBuilder sb, string value)
        {
            sb.Insert(0, value);
        }

        public static void PrependLine(this StringBuilder sb, string value)
        {
            sb.Insert(0, value + Environment.NewLine);
        }

        #endregion
    }
}

फिर, बस जोड़ें:

using Application.Code.Helpers;

किसी भी वर्ग के शीर्ष पर जिसे आप StringBuilder का उपयोग करना चाहते हैं और किसी भी समय आप StringBuilder चर के साथ intelli-sense का उपयोग करते हैं, Prepend और PrependLine विधियाँ दिखाई देंगी। बस याद रखें कि जब आप Prepend का उपयोग करते हैं, तो आपको उल्टे क्रम में Prepend करने की आवश्यकता होगी, यदि आप आवेदन कर रहे थे।


0

यह काम करना चाहिए:

aStringBuilder = "newText" + aStringBuilder; 

.NET में, यह पूरी तरह से मान के stringसाथ काम करता है, लेकिन प्रकार के मूल्यों के साथ काम नहीं करता है StringBuilder। @ScubaSteve का उत्तर अच्छी तरह से काम करता है।
कंटैंगो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.