मुझे पता है कि हम StringBuilder
का उपयोग कर तारों को जोड़ सकते हैं। क्या StringBuilder
का उपयोग करके हम तारों को प्रीपेड कर सकते हैं (यानी स्ट्रिंग के सामने तार जोड़ सकते हैं) ताकि हम प्रदर्शन लाभों को StringBuilder
ऑफ़र रख सकें?सी # या जावा: स्ट्रिंगबिल्डर के साथ स्ट्रिंग तैयार करें?
उत्तर
0 पर सेट स्थिति पैरामीटर के साथ सम्मिलित विधि का उपयोग करना प्रीपेडिंग (यानी शुरुआत में डालने) जैसा ही होगा।
यह काम करता है दोनों C#
स्ट्रिंगबिल्डर जावा के लिए डालें: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html#insert(int,%20boolean) –
प्रासंगिक API के लिए सही जावाडॉक है : http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuilder.html#insert(int,%20java.lang.CharSequence%29 – ArtB
StringBuilder str = new StringBuilder();
str.Insert(0, "text");
के लिए और Java संपादित करें: स्वरूपित कोड
StringBuilder MyStringBuilder = new StringBuilder("World!");
MyStringBuilder.Insert(0,"Hello "); // Hello World!
का उपयोग कर एक स्ट्रिंग prepending के बाद प्रविष्टि कुछ संकेत करते आमतौर पर कॉपी करने के लिए सब कुछ की आवश्यकता होगी प्रयास करें बैकिंग सरणी में, इसलिए यह अंत तक जोड़ने के जितना तेज़ नहीं होगा।
लेकिन आप जावा में इस तरह यह कर सकते हैं (सी # में यह एक ही है, लेकिन विधि Insert
कहा जाता है):
aStringBuilder.insert(0, "newText");
अगर मैं तुम्हें सही ढंग से समझ, insert method लगता है कि यह क्या करेंगे तुम्हें चाहिए। बस स्ट्रिंग डालने पर ऑफसेट 0.
आप एक विस्तार विधि की कोशिश कर सकते:
/// <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!
आप पहले जोड़ता है की बहुत सारी के साथ उच्च प्रदर्शन की आवश्यकता होती है, तो आप StringBuilder
के अपने स्वयं के संस्करण लिखने के लिए की आवश्यकता होगी (या उपयोग किसी और का)। मानक StringBuilder
के साथ (हालांकि तकनीकी रूप से इसे अलग-अलग कार्यान्वित किया जा सकता है) सम्मिलन बिंदु के बाद डेटा कॉपी करने की आवश्यकता होती है। पाठ के एन टुकड़े को सम्मिलित करना ओ (एन^2) समय ले सकता है।
एक बेवकूफ दृष्टिकोण char[]
बफर के साथ-साथ लंबाई में ऑफसेट जोड़ने के लिए होगा। जब प्रीपेन्ड के लिए पर्याप्त जगह नहीं है, तो डेटा को कड़ाई से जरूरी से अधिक बढ़ाएं। यह प्रदर्शन को वापस ओ (एन लॉग एन) (मुझे लगता है) में ला सकता है। बफर चक्रीय बनाने के लिए एक और परिष्कृत दृष्टिकोण है। इस तरह सरणी के दोनों सिरों पर अतिरिक्त स्थान संगत हो जाता है।
मैंने इसका उपयोग नहीं किया है, लेकिन Ropes For Java दिलचस्प लगता है। परियोजना का नाम शब्दों पर एक नाटक है, गंभीर काम के लिए स्ट्रिंग के बजाय रस्सी का उपयोग करें। प्रीपेडिंग और अन्य परिचालनों के लिए प्रदर्शन दंड के आसपास हो जाता है। एक नजर के लायक, अगर आप इसमें बहुत कुछ करने जा रहे हैं।
एक रस्सी स्ट्रिंग के लिए एक उच्च प्रदर्शन प्रतिस्थापन है। आंकड़ा संरचना, में विस्तार से वर्णित "रस्सियों: स्ट्रिंग्स के लिए एक वैकल्पिक", asymptotically बेहतर संशोधनों आगे जोड़ते की तरह, संलग्न हटाएं और डालें आम स्ट्रिंग के लिए दोनों स्ट्रिंग और StringBuffer से प्रदर्शन प्रदान करता है। स्ट्रिंग्स की तरह, रस्सियां अपरिवर्तनीय हैं और इसलिए बहु-थ्रेडेड प्रोग्रामिंग में उपयोग के लिए उपयुक्त है।
आप रिवर्स में स्ट्रिंग का निर्माण कर सकते हैं और फिर परिणाम को उलट सकते हैं। आप ओ (एन^2) सबसे खराब केस लागत की बजाय ओ (एन) लागत लेते हैं।
यह केवल तभी काम करता है जब आप व्यक्तिगत रूप से जोड़ रहे हों अन्यथा आपको अपनी प्रत्येक स्ट्रिंग को रिवर्स करने की आवश्यकता होगी जो आकार और संख्या के आधार पर सभी बचत नहीं करेगा। – ArtB
अन्य टिप्पणियों के आधार पर, ऐसा करने का कोई मानक त्वरित तरीका नहीं है। स्ट्रिंगबिल्डर का .Insert(0, "text")
का उपयोग लगभग दर्दनाक धीमी स्ट्रिंग कॉन्सटेनेशन (10000 कॉन्सट्स के आधार पर) के रूप में लगभग 1-3x जितना तेज़ है, इसलिए नीचे एक हजार वर्ग बार संभावित रूप से आगे बढ़ने के लिए एक वर्ग है!
मैं कुछ अन्य बुनियादी कार्यशीलता ऐसे append()
, subString()
और length()
आदि के रूप में दोनों संलग्न कर देता है और पहले जोड़ता है के बारे में दो बार के रूप में तेजी से बदलते हैं धीमी गति से StringBuilder संलग्न कर देता है 3 गुना करने के लिए शामिल किया है। स्ट्रिंगबिल्डर की तरह, इस वर्ग में बफर स्वचालित रूप से बढ़ जाएगा जब पाठ पुराने बफर आकार को बहता है।
कोड का परीक्षण बहुत अधिक किया गया है, लेकिन मैं इसकी बग से मुक्त गारंटी नहीं दे सकता।
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)
}
}
यह काम करना चाहिए:
aStringBuilder = "newText" + aStringBuilder;
.NET में, यह 'स्ट्रिंग' प्रकार के मानों के साथ पूरी तरह से काम करता है, लेकिन 'स्ट्रिंगबिल्डर' प्रकार के मानों के साथ काम नहीं करता है। @ स्कूबास्टवे का उत्तर अच्छी तरह से काम करता है। – Contango
आप एक साधारण वर्ग के साथ StringBuilder खुद के लिए एक्सटेंशन बना सकता है:
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;
आप जिस वर्ग का उपयोग करना चाहते हैं उसके शीर्ष पर स्ट्रिंगबिल्डर किसी भी समय जब आप स्ट्रिंगबिल्डर परिवर्तक के साथ इंटेलि-एन्टर का उपयोग करते हैं, तो प्रीपेन्ड और प्रीपेन्डलाइन विधियां दिखाई देंगी। बस याद रखें कि जब आप प्रीपेन्ड का उपयोग करते हैं, तो आपको रिवर्स ऑर्डर में आगे बढ़ने की आवश्यकता होगी, अगर आप इसमें शामिल थे।
मुझे आपके प्रश्न –
तैयार नहीं हैं। शब्द प्रीपेन्ड है। स्ट्रिंग को प्रीपेड करना एक स्ट्रिंग के दोनों सिरों को एक साथ जोड़ने जैसा कुछ होना चाहिए, मुझे लगता है? –