क्या बार-बार एक स्ट्रिंग को X संख्या में वापस करने का एक आसान तरीका है?


318

मैं एक आइटम की गहराई के आधार पर एक स्ट्रिंग से पहले इंडेंटेशन की एक निश्चित संख्या सम्मिलित करने की कोशिश कर रहा हूं और मैं सोच रहा हूं कि क्या एक स्ट्रिंग को बार-बार वापस करने का कोई तरीका है। उदाहरण:

string indent = "---";
Console.WriteLine(indent.Repeat(0)); //would print nothing.
Console.WriteLine(indent.Repeat(1)); //would print "---".
Console.WriteLine(indent.Repeat(2)); //would print "------".
Console.WriteLine(indent.Repeat(3)); //would print "---------".

9
यकीन नहीं है कि यह लागू है, लेकिन आप IndentTextWriter को भी देखना चाहते हैं ।
क्रिस

क्या आप स्वीकृत उत्तर को बदलने पर विचार करना चाहते हैं क्योंकि आपका प्रश्न स्ट्रिंग्स की पुनरावृत्ति के बारे में है न कि उन पात्रों के बारे में जिन्हें स्वीकृत उत्तर में दर्शाया गया है? आज तक .Net v4.7 के रूप में, Stringवर्ग के किसी भी अतिभारित निर्माता ने इसे दोहराव पैदा करने के लिए एक पैरामीटर के रूप में एक स्ट्रिंग नहीं लिया है, जो स्वीकृत उत्तर को एक उपयुक्त फिट बना सकता था।
RBT

जवाबों:


537

यदि आप केवल उसी चरित्र को दोहराने का इरादा रखते हैं तो आप स्ट्रिंग निर्माता का उपयोग कर सकते हैं जो एक चार को स्वीकार करता है और इसे दोहराने के लिए कई बारnew String(char c, int count)

उदाहरण के लिए, पांच बार डैश को दोहराने के लिए:

string result = new String('-', 5);
Output: -----

7
मुझे इस अच्छी छोटी सुविधा के बारे में याद दिलाने के लिए धन्यवाद। मुझे लगता है कि यह मेरे दिमाग के कोने में खो गया था।
क्रिस

3
चूंकि टैब मेटाचैकर 't' एक चर है जो इंडेंटेशन के लिए भी काम करता है।
cori

91
यह C # की एक बहुत ही उपयोगी ट्रिक है, लेकिन सवाल का शीर्षक एक स्ट्रिंग (एक चार नहीं) के बारे में पूछ रहा है। नीचे दिए गए अन्य उत्तर वास्तव में इस प्रश्न का उत्तर दे रहे हैं, लेकिन बहुत कम रेट किए गए हैं। मैं अहमद के जवाब का अनादर करने की कोशिश नहीं कर रहा हूं, लेकिन मुझे लगता है कि या तो इस सवाल का शीर्षक बदला जाना चाहिए (यदि सवाल वास्तव में पात्रों के बारे में है) या अन्य जवाब वास्तव में उखाड़ फेंकने चाहिए (और यह नहीं)।
pghprogrammer4

14
@ अहद जैसा कि मैंने कहा था, मैंने यह नहीं नकारा क्योंकि मुझे नहीं लगता कि आपने अच्छी जानकारी प्रदान की है, बल्कि इसलिए कि आपके द्वारा दी गई जानकारी वर्तमान में बताए गए प्रश्न का उत्तर देने के लिए प्रासंगिक नहीं है । सोचिए अगर आप स्ट्रिंग्स को दोहराने का तरीका खोज रहे हैं (वर्ण नहीं) और जब आप संबंधित प्रश्न पर पहुँचते हैं तो आपको प्रश्न के वास्तविक उत्तर पाने के लिए कई 'उपयोगी' युक्तियों के माध्यम से स्क्रॉल करना होगा। यदि आप के लिए अपमान करना अपराध है, तो मैं इसे हटा सकता हूं। लेकिन क्या आप देखते हैं कि मैं कहाँ से आ रहा हूँ? क्या मैं यहां पूरी तरह से बंद हूं?
pghprogrammer4

11
@ pghprogrammer4 IMHO, डाउनवोट काफी हतोत्साहित करने वाला हो सकता है, और इसका उपयोग केवल हानिकारक / भ्रामक / सही मायने में जवाब देने के लिए किया जाना चाहिए, जिसमें एक बड़े बदलाव की जरूरत है या उनके लेखक को हटा दिया जाना चाहिए। उत्तर मौजूद हैं क्योंकि लोग उदार हैं और वे जो जानते हैं उसे साझा करना चाहते हैं। आम तौर पर, ये साइटें वास्तव में उत्थान के प्रोत्साहन पर शीर्ष पर उपयोगी उत्तर लाने के लिए होती हैं।
टूलमेकरसैट

271

यदि आप .NET 4.0 का उपयोग कर रहे हैं, तो आप string.Concatएक साथ उपयोग कर सकते हैं Enumerable.Repeat

int N = 5; // or whatever
Console.WriteLine(string.Concat(Enumerable.Repeat(indent, N)));

नहीं तो मैं एडम के जवाब की तरह कुछ लेकर जाऊंगा

आमतौर पर एंड्री के जवाब का उपयोग करने की सलाह देने का कारण यह नहीं है कि कॉल सुपरफ्लूड ओवरहेड का परिचय देता है जो एडम द्वारा सुझाए गए दृष्टिकोण से बचा जाता है । कहा कि, कम से कम यह .NET 4.0 की आवश्यकता के बिना काम करता है; और यह त्वरित और आसान है (यदि दक्षता बहुत अधिक नहीं है तो आपको मारना नहीं है)।ToArray()StringBuilder


3
यह स्ट्रिंग्स के साथ अच्छी तरह से काम करेगा - जैसे अगर आपको गैर-ब्रेकिंग रिक्त स्थान (& nbsp;) को समतल करने की आवश्यकता है। लेकिन मुझे लगता है कि अगर आप एक
चर के

1
स्ट्रिंग निर्माता केवल एक चार के लिए काम करेगा। कॉनटैट रिपीट का उपयोग करने का विकल्प स्ट्रिंग्स के लिए काम करेगा
एली डेगन

4
वास्तविक शीर्षक प्रश्न का उत्तर देने के लिए धन्यवाद!
मार्क के कोवान

मुझे यह उत्तर पसंद है!
Ji_in_coding

यदि आप प्राप्त कर रहे हैं -System.Linq.Enumerable आदि आउटपुट के रूप में, यह इसलिए है क्योंकि आप (ठीक है, यह मैं था) कॉपी / पेस्ट और स्निपेट को संशोधित करने के लिए बहुत जल्दी थे। यदि आपको Enumerable.Repeat के आउटपुट पर एक अलग स्ट्रिंग को समतल करने की आवश्यकता है, तो आपको इसे इस तरह से करना होगा: Console.WriteLine(string.Concat("-", string.Concat(Enumerable.Repeat(indent, N))));
Gabe

47
public static class StringExtensions
{
    public static string Repeat(this string input, int count)
    {
        if (!string.IsNullOrEmpty(input))
        {
            StringBuilder builder = new StringBuilder(input.Length * count);

            for(int i = 0; i < count; i++) builder.Append(input);

            return builder.ToString();
        }

        return string.Empty;
    }
}

6
के रूप में अच्छी तरह से पारित हो सकता है input.Length * countकरने के लिए StringBuilderनिर्माता, आपको नहीं लगता कि?
दान ताओ

और अगर आप पारित input.Length * countकरने के लिए StringBuilderनिर्माता, आप को छोड़ सकता हैStringBuilder पूरी तरह से और सही आकार की एक चार [] अभी पैदा करते हैं।
dtb

@dtb: मैं उत्सुक हूं कि आप ऐसा क्यों करना चाहते हैं। मैं सोच भी नहीं सकता कि यह (यदि कोई हो) एक का उपयोग करने की तुलना में अधिक तेजी से StringBuilderहोगा, और कोड कम पारदर्शी होगा।
एडम रॉबिंसन

@dtb: yuck StringBuilder का उपयोग करें; इसे कुशलतापूर्वक करने के लिए डिजाइन किया गया था।
टूलमेकरसैट

एडम, मैं देख रहा हूँ कि आप इसे गिनने के लिए जोड़ते समय अशक्त के लिए परीक्षण इनपुट की परेशानी में चले गए, लेकिन फिर अनुमति दी कि नीचे गिरने के लिए कुछ भी नहीं करने के लिए एपेंड पर भरोसा करते हुए। IMHO यह स्पष्ट से कम है: यदि अशक्त एक संभावित इनपुट है, तो उस अप फ्रंट के लिए परीक्षण क्यों नहीं किया जाता है, और खाली स्ट्रिंग लौटाता है?
टूलमेकरसैट

46

स्ट्रिंग के लिए सबसे अच्छा समाधान

string result = new StringBuilder().Insert(0, "---", 5).ToString();

1
यकीन है कि एक सुंदर एक लाइनर है। निश्चित रूप से सबसे अधिक प्रदर्शन करने वाला नहीं है। StringBuilder में बहुत कम संख्या में उपरीकरण होता है।
तीज

25

कई परिदृश्यों के लिए, यह शायद सबसे साफ समाधान है:

public static class StringExtensions
{
    public static string Repeat(this string s, int n)
        => new StringBuilder(s.Length * n).Insert(0, s, n).ToString();
}

उपयोग तब है:

text = "Hello World! ".Repeat(5);

यह अन्य उत्तरों (विशेषकर @ c0rd) पर बनाता है। सादगी के साथ-साथ, इसमें निम्नलिखित विशेषताएं हैं, जो अन्य सभी तकनीकों पर चर्चा नहीं करते हैं:

  • किसी भी लम्बाई के तार की पुनरावृत्ति, न केवल एक चरित्र (जैसा कि ओपी द्वारा अनुरोध किया गया है)।
  • StringBuilderभंडारण प्रचार के माध्यम से कुशल उपयोग ।

मैं सहमत हूं, यह अद्भुत है। मैंने इसे बॉब के लिए क्रेडिट के साथ अपने कोड में जोड़ा! धन्यवाद!
जॉन बर्टली

22

String.PadLeft का उपयोग करें , यदि आपके वांछित स्ट्रिंग में केवल एक ही चार्ट है

public static string Indent(int count, char pad)
{
    return String.Empty.PadLeft(count, pad);
}

श्रेय यहाँ के कारण


1
चुम्मा। वैसे भी हमें StringBuilders और एक्सटेंशन की क्या आवश्यकता है? यह एक बहुत ही साधारण समस्या है।
DOK

1
मुझे पता नहीं, यह समस्या को हल करने के लिए लगता है जैसे कुछ लालित्य के साथ। और btw, आप किसे 'S' कह रहे हैं? :-)
स्टीव टाउनसेंड

7
लेकिन क्या यह वास्तव में stringकंस्ट्रक्टरcharint का कम स्पष्ट संस्करण नहीं है जो एक और एक लेता है ?
दान ताओ

यह स्ट्रिंग के साथ अच्छा लगेगा। "" के बजाय खाली ... "अन्यथा, अच्छा समाधान;)
थॉमस लेवेस्क

@Steve BTW String.PadLeftतर्कों को उलट दिया जाता है। countगद्दी चरित्र पहले आता है।
अहमद मजीद

17

आप अपनी स्ट्रिंग दोहरा सकते हैं (यदि यह एक चार नहीं है) और परिणाम को संक्षिप्त करें, जैसे:

String.Concat(Enumerable.Repeat("---", 5))

12

मैं दान ताओ के उत्तर के लिए जाऊंगा, लेकिन यदि आप .NET 4.0 का उपयोग नहीं कर रहे हैं तो आप ऐसा कुछ कर सकते हैं:

public static string Repeat(this string str, int count)
{
    return Enumerable.Repeat(str, count)
                     .Aggregate(
                        new StringBuilder(),
                        (sb, s) => sb.Append(s))
                     .ToString();
}

3
मैं findthis अपने प्रोजेक्ट में झलकी करेंगे, तो मुझे आश्चर्य है कि किसने KISS का उल्लंघन किया गया है और क्यों ... अच्छा अन्यथा
Noctis

4
        string indent = "---";
        string n = string.Concat(Enumerable.Repeat(indent, 1).ToArray());
        string n = string.Concat(Enumerable.Repeat(indent, 2).ToArray());
        string n = string.Concat(Enumerable.Repeat(indent, 3).ToArray());

1
@ एडम: मुझे लगता है कि आपको उस प्री- .NET 4.0 को करने की आवश्यकता होगी।
दान ताओ

3

मुझे दिया गया उत्तर पसंद है। हालांकि, मैंने जो अतीत में उपयोग किया है, उसकी पंक्तियों के साथ:

"" .PadLeft (3 * इंडेंट, '-')

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

int Indent = 2;

string[] sarray = new string[6];  //assuming max of 6 levels of indent, 0 based

for (int iter = 0; iter < 6; iter++)
{
    //using c0rd's stringbuilder concept, insert ABC as the indent characters to demonstrate any string can be used
    sarray[iter] = new StringBuilder().Insert(0, "ABC", iter).ToString();
}

Console.WriteLine(sarray[Indent] +"blah");  //now pretend to output some indented line

हम सभी एक चतुर समाधान पसंद करते हैं लेकिन कभी-कभी सरल सबसे अच्छा होता है।


3

मैं अपनी सभी परियोजनाओं में एक्सटेंशन विधि का उपयोग कर रहा हूं:

public static string Repeat(this string text, int count)
{
    if (!String.IsNullOrEmpty(text))
    {
        return String.Concat(Enumerable.Repeat(text, count));
    }
    return "";
}

आशा है कि कोई इसका उपयोग कर सकता है ...


2

आश्चर्यचकित कोई पुराने स्कूल नहीं गया। मैं इस कोड के बारे में कोई दावा नहीं कर रहा हूं , लेकिन सिर्फ मनोरंजन के लिए:

public static string Repeat(this string @this, int count)
{
    var dest = new char[@this.Length * count];
    for (int i = 0; i < dest.Length; i += 1)
    {
        dest[i] = @this[i % @this.Length];
    }
    return new string(dest);
}

जाहिर है कि मैंने उस कसौटी पाठक के लिए एक परीक्षण के रूप में छोड़ दिया :) बहुत सूक्ष्म, धन्यवाद।
OlduwanSteve

1
एक पैरामीटर @this नामकरण के बारे में कुछ भी पुराना नहीं है, यह हमेशा एक भयानक विचार है :)
डेव जेलिसन

2
जब तक एमवीसी के साथ काम करने के लिए मजबूर नहीं किया जाता है, तब तक जब तक कि आपको एमवीसी के साथ काम करने की आवश्यकता न हो, तब तक मैं वेरिएबल नाम के रूप में कीवर्ड का उपयोग नहीं करना चाहता हूं (जैसे @class = "कुछ" क्योंकि आप सीएसएस के संदर्भ में क्लास की आवश्यकता है लेकिन यह सी # में एक कीवर्ड है)। यह अंगूठे का एक सामान्य नियम है। हालांकि यह निश्चित रूप से अनिवार्य कोड और वैध है, पढ़ने में आसानी और टाइपिंग, दोनों व्यावहारिक कारणों के बारे में सोचें। मैं पहले क्या हो रहा है, इसलिए यह वर्णन करने के लिए पैरामीटर नामों का उपयोग करने के लिए बहुत आंशिक हूं। यह स्ट्रिंग बीज, int count) अधिक चित्रण imho हो सकता है।
डेव जेलिसन

1
दिलचस्प है, धन्यवाद। मुझे लगता है कि इस मामले में आप शायद सही हैं कि @this कम वर्णनात्मक है जितना कि हो सकता है। हालांकि सामान्य तौर पर मुझे लगता है कि कक्षाओं या इंटरफेस का विस्तार होना काफी आम है, जहां 'इस' के लिए केवल उचित नाम ही सामान्य है। यदि आपके पास 'उदाहरण' या 'इट' या 'स्ट्र' '( एमएसडीएन देखें ) नामक एक पैरामीटर है तो आपका जो मतलब है वह' यह 'है।
OlduwanSteve

1
मैं मूल रूप से आपके साथ सहमत हूं, लेकिन तर्क के लिए ... चूंकि मैं उस स्ट्रिंग के बारे में अधिक जानता हूं जो मैं बना रहा हूं, मैं स्ट्रिंगबर्ल की तुलना में थोड़ा बेहतर काम कर सकता हूं। मेमोरी आवंटित करते समय स्ट्रिंगबुलस्ट को एक अनुमान लगाना पड़ता है। दी गई है कि यह कई परिदृश्यों में बात करने की संभावना नहीं है, लेकिन किसी को बाहर समानांतर में दोहराया तारों की एक बड़ी संख्या का निर्माण हो सकता है और वापस कुछ घड़ी चक्र हासिल करने के लिए खुश हो :)
OlduwanSteve

2

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

int indentCount = 3;
string indent = "---";
string stringToBeIndented = "Blah";
// Need dummy char NOT in stringToBeIndented - vertical tab, anyone?
char dummy = '\v';
stringToBeIndented.PadLeft(stringToBeIndented.Length + indentCount, dummy).Replace(dummy.ToString(), indent);

वैकल्पिक रूप से, यदि आप जानते हैं कि आप कितने स्तरों की अधिकतम संख्या की अपेक्षा कर सकते हैं, तो आप इसमें एक सारणी और सूचकांक की घोषणा कर सकते हैं। आप शायद इस ऐरे को स्थिर या स्थिर बनाना चाहेंगे।

string[] indents = new string[4] { "", indent, indent.Replace("-", "--"), indent.Replace("-", "---"), indent.Replace("-", "----") };
output = indents[indentCount] + stringToBeIndented;      

2

मेरे पास एडम के जवाब पर टिप्पणी करने के लिए पर्याप्त प्रतिनिधि नहीं है, लेकिन इसे करने का सबसे अच्छा तरीका इस तरह है:

public static string RepeatString(string content, int numTimes) {
        if(!string.IsNullOrEmpty(content) && numTimes > 0) {
            StringBuilder builder = new StringBuilder(content.Length * numTimes);

            for(int i = 0; i < numTimes; i++) builder.Append(content);

            return builder.ToString();
        }

        return string.Empty;
    }

आपको यह देखने के लिए जांचना होगा कि क्या अंकतालिका अधिक है तो शून्य है, अन्यथा आपको अपवाद मिलेगा।


2

मैंने इसका हल नहीं देखा। मुझे यह सरल लगता है कि मैं वर्तमान में सॉफ्टवेयर विकास में कहां हूं:

public static void PrintFigure(int shapeSize)
{
    string figure = "\\/";
    for (int loopTwo = 1; loopTwo <= shapeSize - 1; loopTwo++)
    {
        Console.Write($"{figure}");
    }
}

2

सामान्य उपयोग के लिए, StringBuilder वर्ग से जुड़े समाधान बहु-वर्ण स्ट्रिंग्स को दोहराने के लिए सर्वोत्तम हैं। यह बड़ी संख्या में तार के संयोजन को इस तरह से संभालने के लिए अनुकूलित है कि सरल संयोजन नहीं हो सकता है और यह हाथ से अधिक कुशलता से करना मुश्किल या असंभव होगा। यहां दिखाए गए StringBuilder समाधान O (N) का उपयोग करते हैं पुनरावृत्तियों को पूरा करने के लिए , एक सपाट दर जो बार-बार दोहराई जाती है।

हालांकि, बहुत बड़ी संख्या में दोहराए जाने के लिए, या जहां दक्षता के उच्च स्तर से बाहर निचोड़ा जाना चाहिए, एक बेहतर तरीका है स्ट्रिंगब्यूलर की बुनियादी कार्यक्षमता के समान कुछ करना लेकिन मूल स्ट्रिंग के बजाय गंतव्य से अतिरिक्त प्रतियां तैयार करना, नीचे के अनुसार।

    public static string Repeat_CharArray_LogN(this string str, int times)
    {
        int limit = (int)Math.Log(times, 2);
        char[] buffer = new char[str.Length * times];
        int width = str.Length;
        Array.Copy(str.ToCharArray(), buffer, width);

        for (int index = 0; index < limit; index++)
        {
            Array.Copy(buffer, 0, buffer, width, width);
            width *= 2;
        }
        Array.Copy(buffer, 0, buffer, width, str.Length * times - width);

        return new string(buffer);
    }

यह प्रत्येक पुनरावृत्ति के साथ स्रोत / गंतव्य स्ट्रिंग की लंबाई को दोगुना कर देता है, जो हर बार जब यह मूल स्ट्रिंग से गुजरता है, तो काउंटर को रीसेट करने के ओवरहेड को बचाता है, बजाय सुचारू रूप से पढ़ने और अब लंबे स्ट्रिंग को कॉपी करने के, आधुनिक प्रोसेसर बहुत कुछ कर सकते हैं अधिक कुशलता से।

यह एक बेस -2 लॉगरिदम का उपयोग करता है ताकि यह पता लगाया जा सके कि स्ट्रिंग की लंबाई को दोगुना करने के लिए कितनी बार जरूरत है और फिर ऐसा करने के लिए आगे बढ़ता है। चूँकि नकल की जाने वाली शेष राशि अब उस कुल लंबाई से कम है जिसकी वह नकल कर रहा है, इसलिए यह केवल पहले से उत्पन्न एक उपसमूह की प्रतिलिपि बना सकता है।

मैंने StringBuilder के उपयोग पर Array.Copy () पद्धति का उपयोग किया है, StringBuilder की सामग्री की प्रतिलिपि बनाने के रूप में अपने आप में प्रत्येक पुनरावृत्ति के साथ उस सामग्री के साथ एक नया स्ट्रिंग बनाने का ओवरहेड होगा। Array.Copy () इस से बचा जाता है, जबकि अभी भी दक्षता की अत्यधिक उच्च दर के साथ काम कर रहा है।

यह समाधान पूरा करने के लिए O (1 + log N) पुनरावृत्तियों को लेता है , एक दर जो दोहराव की संख्या के साथ तार्किक रूप से बढ़ती है (दोहराए जाने की संख्या एक अतिरिक्त पुनरावृत्ति के बराबर होती है), अन्य तरीकों पर पर्याप्त बचत, जो आनुपातिक रूप से होती है।


1

एक अन्य दृष्टिकोण के stringरूप में विचार करना है IEnumerable<char>और एक सामान्य विस्तार विधि है जो निर्दिष्ट कारक द्वारा संग्रह में आइटमों को गुणा करेगी।

public static IEnumerable<T> Repeat<T>(this IEnumerable<T> source, int times)
{
    source = source.ToArray();
    return Enumerable.Range(0, times).SelectMany(_ => source);
}

तो आपके मामले में:

string indent = "---";
var f = string.Concat(indent.Repeat(0)); //.NET 4 required
//or
var g = new string(indent.Repeat(5).ToArray());

1

पुनरावृत्ति के साथ एक लाइन प्रिंट करें।

Console.Write(new string('=', 30) + "\n");

==============================


आपने स्ट्रिंग के अंत में \ n को जोड़ने के बजाय Console.WriteLine का उपयोग क्यों नहीं किया?
inxaneNinja

-1

आप ऐसा करने के लिए एक ExtensionMethod बना सकते हैं!

public static class StringExtension
{
  public static string Repeat(this string str, int count)
  {
    string ret = "";

    for (var x = 0; x < count; x++)
    {
      ret += str;
    }

    return ret;
  }
}

या @ दान ताओ समाधान का उपयोग करना:

public static class StringExtension
{
  public static string Repeat(this string str, int count)
  {
    if (count == 0)
      return "";

    return string.Concat(Enumerable.Repeat(indent, N))
  }
}

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