जावा में एक स्ट्रिंग को दोहराने का सरल तरीका


597

मैं एक साधारण कॉमन्स विधि या ऑपरेटर की तलाश कर रहा हूं जो मुझे कुछ स्ट्रिंग एन को दोहराने की अनुमति देता है । मुझे पता है कि मैं इसे लूप के लिए लिख सकता हूं, लेकिन मैं चाहता हूं कि जब भी आवश्यक हो और एक सरल प्रत्यक्ष विधि कहीं मौजूद न हो तो लूप से बचना चाहिए।

String str = "abc";
String repeated = str.repeat(3);

repeated.equals("abcabcabc");

से संबंधित:

किसी अन्य स्ट्रिंग को दिए गए समय की संख्या को दोहराकर स्ट्रिंग जावास्क्रिप्ट को बनाएं

संपादित

जब वे पूरी तरह से आवश्यक नहीं होते हैं तो मैं छोरों से बचने की कोशिश करता हूं:

  1. वे कोड की लाइनों की संख्या को जोड़ते हैं, भले ही वे किसी अन्य फ़ंक्शन में टक किए गए हों।

  2. मेरे कोड को पढ़ने वाले को यह पता लगाना होगा कि मैं क्या कर रहा हूं। यहां तक ​​कि अगर यह टिप्पणी की गई है और इसमें सार्थक चर नाम हैं, तो उन्हें अभी भी यह सुनिश्चित करना है कि यह "चतुर" कुछ भी नहीं कर रहा है।

  3. प्रोग्रामर को चतुर चीजों को छोरों के लिए रखना पसंद है, भले ही मैं इसे "केवल वही करें जो यह करने का इरादा है", जो किसी के साथ आने और कुछ अतिरिक्त चतुर "फिक्स" को जोड़ने के लिए नहीं रोकता है।

  4. वे अक्सर गलत होने में आसान होते हैं। अनुक्रमणिका से जुड़े छोरों के लिए एक कीड़े से उत्पन्न होते हैं।

  5. लूप के लिए अक्सर एक ही चर का पुन: उपयोग होता है, जिससे स्कूपिंग कीड़े को खोजने के लिए वास्तव में कठिन होने की संभावना बढ़ जाती है।

  6. लूप के लिए स्थानों की संख्या में वृद्धि होती है जहां एक बग शिकारी को देखना पड़ता है।


35
मैं समझता हूं कि लूप के लिए कुछ वास्तविक मुद्दे हो सकते हैं। लेकिन आपको "हर कीमत पर" छोरों से बचने की कोशिश नहीं करनी चाहिए क्योंकि अगर यह आपके लिए पठनीयता, स्थिरता और गति पर खर्च करता है, तो आप प्रतिशोधी हो रहे हैं। यह उन मामलों में से एक है।
इमेजिस्ट

9
"वे कोड की पंक्तियों की संख्या को जोड़ते हैं, भले ही वे किसी अन्य फ़ंक्शन में टक गए हों" ... वाह, बस वाह। बिग-ओ, एलओसी नहीं
प्योरोलॉजिकल

7
@imagist मैं उन स्थितियों में छोरों से बच रहा हूं जहां यह मुझे पठनीयता, और स्थिरता बनाए रखता है। मैं गति को सबसे कम महत्वपूर्ण मुद्दा मानता हूं (वास्तव में एक गैर-मुद्दा)। मुझे लगता है कि लूप के लिए उपयोग किया जाता है और मैं केवल छोरों के लिए उपयोग करने के लिए सीखने की कोशिश कर रहा हूं जब वे आवश्यक होते हैं और डिफ़ॉल्ट समाधान के रूप में नहीं।
एथन हेइल्मन

3
@Pyrolinary मैं प्रदर्शन या स्पर्शोन्मुख लाभ का दावा नहीं कर रहा हूँ। बल्कि यह कहते हुए कि कोड को कम करके, और पहिया को सुदृढ़ करने के बजाय पुस्तकालय कार्यों का उपयोग करके, मैं पठनीयता को बढ़ाते हुए बग सतह क्षेत्र (कोड की पंक्तियों) को कम करता हूं। दोनों अच्छी बातें मुझे यकीन है कि आप सहमत होंगे।
एथन हेइलमैन

4
@ e5; वर्षों बाद पोस्ट करने के लिए खेद है। मुझे यह प्रश्न इतना उपयुक्त लगता है। यदि किसी विधि में डाला जाता है, तो तर्कों का परीक्षण किया जाना चाहिए (बार> = 0), त्रुटियों को फेंक दिया जाता है। यह मजबूती को जोड़ता है, लेकिन पढ़ने के लिए कोड की लाइनें भी। एक स्ट्रिंग को दोहराना कुछ असंदिग्ध है। कौन पढ़ता है कि कोड वास्तव में जानता है कि स्ट्रिंग क्या करती है। एक टिप्पणी के बिना या javadoc.If की एक पंक्ति के बिना भी हम क्या करते हैं। यदि हम एक स्थिर पुस्तकालय का उपयोग करते हैं, तो यह सोचना उचित है कि इतना सरल कार्य कोई बग नहीं है, YET "मजबूती" चेक के कुछ रूप का परिचय देता है, जिसके बारे में हमें चिंता करने की आवश्यकता है। यदि मैं 10 सुधारों को पूछ सकता हूं, तो (इस तरह की) चीजें एक होंगी।
अगस्टिनोक्स

जवाबों:


229

String::repeat

". ".repeat( 7 )  // Seven period-with-space pairs: . . . . . . . 

जावा 11 में नया वह तरीका String::repeatहै जो आपके द्वारा पूछा गया है:

String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");

इसके जावदोक कहते हैं:

/**
 * Returns a string whose value is the concatenation of this
 * string repeated {@code count} times.
 * <p>
 * If this string is empty or count is zero then the empty
 * string is returned.
 *
 * @param count number of times to repeat
 *
 * @return A string composed of this string repeated
 * {@code count} times or the empty string if this
 * string is empty or count is zero
 *
 * @throws IllegalArgumentException if the {@code count} is
 * negative.
 *
 * @since 11
 */ 

2
इसके लिए @Nicolai स्रोत कोड, किसी के मामले में बस hg.openjdk.java.net/jdk/jdk/file/fc16b5f193c7/src/java.base/…
यूजीन

7
मैंने अभी तक जावा 9 को सड़क पर नहीं देखा है (और लंबे समय तक नहीं होगा ..) - और 11 जाहिरा तौर पर जहाज करने के लिए सेट है ..
javadba

1
शायद स्पष्ट है, लेकिन आप इस विधि को एक स्ट्रिंग शाब्दिक पर भी कह सकते हैं:"abc".repeat(3)
Boann

895

यहाँ सबसे छोटा संस्करण है (जावा 1.5+ आवश्यक):

repeated = new String(new char[n]).replace("\0", s);

कहाँ nजाने की संख्या आप स्ट्रिंग दोहराना चाहते हैं औरs स्ट्रिंग को दोहराने के लिए है।

कोई आयात या पुस्तकालयों की जरूरत नहीं।


22
मुझे नहीं लगता कि यह बिल्कुल भी गलत है। आदिम प्रकार ( char[]इस मामले में) नल के साथ तात्कालिक होते हैं, फिर एक Stringसे बनाया जाता है char[], और नल replaced()आपके द्वारा इच्छित चरित्र के साथ हैंs
Amarok

32
हालांकि यह बहुत चालाक है (+1) मुझे लगता है कि यह बहुत हद तक इस बात को साबित करता है कि छोरों के लिए अक्सर स्पष्ट कोड होते हैं
रिचर्ड टिंगल

75
उन लोगों के लिए जो मोटापे के बारे में शिकायत करते हैं, पठनीयता साक्षरता पर निर्भर करती है। यह पूरी तरह से स्पष्ट है कि यह क्या करता है और उन लोगों के लिए शैक्षिक है जो इसे तुरंत नहीं देख सकते हैं। यह आपको जावा के साथ मिलता है।
डैनसालमो

11
...replace('\0', str)स्ट्रिंग संस्करण के बजाय बेहतर प्रदर्शन के लिए उपयोग किया जाना चाहिए।
user686249

11
@ user686249: केवल replace(char oldChar, char newChar)और replace(CharSequence target, CharSequence replacement)इसलिए मैं यह नहीं देखता कि यह कैसे काम कर सकता है
user102008

334

यदि आप जावा <= 7 का उपयोग कर रहे हैं , तो यह "संक्षिप्त" है जैसा कि यह मिलता है:

// create a string made up of n copies of string s
String.format("%0" + n + "d", 0).replace("0", s);

में जावा 8 और ऊपर अधिक पठनीय रास्ता है:

// create a string made up of n copies of string s
String.join("", Collections.nCopies(n, s));

अंत में, जावा 11 और उससे ऊपर के लिए, repeat​(int count)विशेष रूप से इसके लिए एक नया तरीका है ( लिंक )

"abc".repeat(12);

वैकल्पिक रूप से, यदि आपकी परियोजना जावा पुस्तकालयों का उपयोग करती है तो अधिक विकल्प हैं।

के लिए अपाचे कॉमन्स :

StringUtils.repeat("abc", 12);

के लिए गूगल अमरूद :

Strings.repeat("abc", 12);

4
nशून्य होने पर पूर्व अपवाद का कारण बनता है।
शक १०२

जावा 8 का उदाहरण संकलित नहीं करता है -> टाइप मिसमैच: सूची से नहीं बदल सकता <चरित्र> के लिए
समानता

6
@ एग्रीन sको स्ट्रिंग होना है, न किChar
कैनर

@ करन धन्यवाद। मेरा बुरा, मैं माफी माँगता हूँ। जाहिर तौर पर मैं कल बहुत थक गया था। डाउनवोटिंग के बारे में क्षमा करें। मैं जितनी जल्दी हो सके
डाउनवोट को हटा दूंगा

@ कोई समस्या नहीं है, यह स्पष्ट कर दिया है कि अब एक स्ट्रिंग है
Caner

312

कॉमन्स लैंग स्ट्रिंगरंगिल्स। क्रीप ()

उपयोग:

String str = "abc";
String repeated = StringUtils.repeat(str, 3);

repeated.equals("abcabcabc");

99
लंबे समय में सादगी के लिए एक-विधि-निर्भरता का उपयोग करने के परिणामस्वरूप जार-नरक हो सकता है
dfa

81
यकीन है, सिवाय इसके कि यह कॉमन्स लैंग है। मुझे नहीं लगता कि मैंने कभी 5000 LOCS पर एक परियोजना देखी है जिसमें कॉमन्स लैंग नहीं था।
एथन हेइलमैन

11
कॉमन्स लैंग खुला स्रोत है - इसे डाउनलोड करें और एक नज़र डालें। बेशक इसमें एक लूप है, लेकिन यह बिल्कुल सरल नहीं है। बहुत सारे प्रयास प्रोफाइलिंग और उस कार्यान्वयन के अनुकूलन में चले गए।
ChssPly76

28
मैं प्रदर्शन कारण के लिए छोरों से नहीं बचता (प्रश्न में मेरे कारण पढ़ें)। जब कोई StringUtils.repeat देखता है, तो वे जानते हैं कि मैं क्या कर रहा हूँ। उन्हें यह चिंता करने की आवश्यकता नहीं है कि मैंने दोहराने के अपने स्वयं के संस्करण को लिखने का प्रयास किया और गलती की। यह एक परमाणु संज्ञानात्मक इकाई है!
एथन हेइल्मन

7
@ Thorbjørn रेवन एंडरसन - यह बहुत दिलचस्प हो सकता है अगर चीजें संदर्भ से बाहर रखी जा रही हों
ChssPly76

140

इसके String.joinसाथ संयोजन के रूप में जावा 8 एक सुव्यवस्थित तरीका प्रदान करता है Collections.nCopies:

// say hello 100 times
System.out.println(String.join("", Collections.nCopies(100, "hello")));

7
धन्यवाद! Android TextUtils.join () के लिए String.join () के बजाय इस्तेमाल किया जा सकता है
MinaHany

2
इस उत्तर के लिए धन्यवाद। यह किसी भी बाहरी एपीआई ओडर उपयोगिता पद्धति का उपयोग किए बिना सबसे साफ तरीका लगता है! बहुत अच्छा!!
एंड्रियास एम। ओबेरहैम

2
इस विधि के बारे में अच्छी बात यह है कि इसमें शामिल होने से आप एक अलग चरित्र प्रदान कर सकते हैं, जो कि बहुत उपयोगी साबित होता है यदि आप एक सीएसवी सूची बनाते हैं। अन्य सभी तरीकों के साथ आपके पास एक समाप्ति ज्वाइनिंग कैरेक्टर है जिसे अलग ऑपरेशन में निकालने की जरूरत है।
DroidOS

102

यहां केवल मानक स्ट्रिंग फ़ंक्शन और कोई स्पष्ट लूप का उपयोग करने का एक तरीका है:

// create a string made up of  n  copies of  s
repeated = String.format(String.format("%%%ds", n), " ").replace(" ",s);

5
कमाल है :-) हालांकि शून्य बनने के खबरदार ...!
यांग मेयर

4
@ वीजय देव और फोरट्रान: नहीं, उनका मतलब था replace()। जावा 1.5+ में, इसका ओवरलोड संस्करण है, replace()जिसमें दो CharSequences (जिसमें Strings शामिल हैं ) हैं: download.oracle.com/javase/1.5.0/docs/api/java/lang/…
user102008

79
आउच। यह बदसूरत है।
कारेल बिलेक

8
@mzuba मान लें कि n=3देखो कुछ करने के लिए यह पहली प्रारूपों एक स्ट्रिंग की तरह: %03d( %%, जो 3 गद्दी शून्य है, तो प्रारूपों जोड़ने के लिए स्वरूपण कोड है प्रतिशत चिह्न से बचने के लिए है) 0उस के साथ, के लिए अग्रणी 000, और अंत में प्रत्येक की जगह 0तार के साथ
फोरट्रान

15
आप समाधान को कम बदसूरत और समझने में आसान बना सकते हैं: String.format ("% 0" + n + "d, 0) .replace (" 0 ", s)
आर्टूर

87

यदि आप मेरे जैसे हैं और Google अमरूद का उपयोग करना चाहते हैं न कि अपाचे कॉमन्स का। आप अमरूद स्ट्रिंग्स क्लास में रिपीट विधि का उपयोग कर सकते हैं ।

Strings.repeat("-", 60);

2
... और नई निर्भरता के 3Mb प्राप्त करें।
०२:०५ पर मोनोथ्रेड

6
@MonoThreaded मैंने सोचा कि यह बिना कहे चले जाएंगे, लेकिन अमरूद को केवल एक स्ट्रिंग दोहराने के लिए शामिल न करें। मेरा उत्तर इस बारे में था कि यदि आप पहले से ही अमरूद का उपयोग कर रहे हैं तो यह है कि आप इसे कैसे करेंगे।
जैक

53

साथ में , आप भी उपयोग कर सकते हैं Stream.generate

import static java.util.stream.Collectors.joining;
...
String repeated = Stream.generate(() -> "abc").limit(3).collect(joining()); //"abcabcabc"

और यदि आवश्यक हो तो आप इसे एक साधारण उपयोगिता विधि में लपेट सकते हैं:

public static String repeat(String str, int times) {
   return Stream.generate(() -> str).limit(times).collect(joining());
}

6
... या return IntStream.range(0, times).mapToObj(i -> str).collect(joining());जो बेहतर समांतर है
एलेक्सिस सी।

32

तो आप छोरों से बचना चाहते हैं?

यहां आप इसे रखते हैं:

public static String repeat(String s, int times) {
    if (times <= 0) return "";
    else return s + repeat(s, times-1);
}

(बेशक मुझे पता है कि यह बदसूरत और अक्षम है, लेकिन इसमें लूप नहीं है :-p)

आप इसे सरल और सुंदर चाहते हैं? अजगर का उपयोग करें:

s * 3

संपादित करें : चलो इसे थोड़ा सा अनुकूलित करें :-D

public static String repeat(String s, int times) {
   if (times <= 0) return "";
   else if (times % 2 == 0) return repeat(s+s, times/2);
   else return s + repeat(s+s, times/2);
}

Edit2 : मैंने 4 मुख्य विकल्पों के लिए एक त्वरित और गंदा बेंचमार्क किया है, लेकिन मेरे पास साधन प्राप्त करने के लिए इसे चलाने के लिए कई बार समय नहीं है और कई आदानों के लिए बार प्लॉट करना है ... इसलिए यदि कोई चाहता है तो यहां कोड है इसे करने की कोशिश:

public class Repeat {
    public static void main(String[] args)  {
        int n = Integer.parseInt(args[0]);
        String s = args[1];
        int l = s.length();
        long start, end;

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatLog2(s,i).length()!=i*l) throw new RuntimeException();
        }
        end = System.currentTimeMillis();
        System.out.println("RecLog2Concat: " + (end-start) + "ms");

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatR(s,i).length()!=i*l) throw new RuntimeException();
        }               
        end = System.currentTimeMillis();
        System.out.println("RecLinConcat: " + (end-start) + "ms");

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatIc(s,i).length()!=i*l) throw new RuntimeException();
        }
        end = System.currentTimeMillis();
        System.out.println("IterConcat: " + (end-start) + "ms");

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatSb(s,i).length()!=i*l) throw new RuntimeException();
        }
        end = System.currentTimeMillis();
        System.out.println("IterStrB: " + (end-start) + "ms");
    }

    public static String repeatLog2(String s, int times) {
        if (times <= 0) {
            return "";
        }
        else if (times % 2 == 0) {
            return repeatLog2(s+s, times/2);
        }
        else {
           return s + repeatLog2(s+s, times/2);
        }
    }

    public static String repeatR(String s, int times) {
        if (times <= 0) {
            return "";
        }
        else {
            return s + repeatR(s, times-1);
        }
    }

    public static String repeatIc(String s, int times) {
        String tmp = "";
        for (int i = 0; i < times; i++) {
            tmp += s;
        }
        return tmp;
    }

    public static String repeatSb(String s, int n) {
        final StringBuilder sb = new StringBuilder();
        for(int i = 0; i < n; i++) {
            sb.append(s);
        }
        return sb.toString();
    }
}

इसमें 2 तर्क दिए गए हैं, पहला पुनरावृत्तियों की संख्या है (प्रत्येक फ़ंक्शन 1..n से दोहराए गए समय arg के साथ चलता है) और दूसरा दोहराव के लिए स्ट्रिंग है।

अब तक, विभिन्न इनपुट्स के साथ चलने वाले समय का त्वरित निरीक्षण रैंकिंग को कुछ इस तरह से छोड़ता है (बेहतर से बदतर):

  1. Iterative StringBuilder परिशिष्ट (1x)।
  2. पुनरावर्ती संघटन log2 आह्वान (~ 3x)।
  3. पुनरावर्ती अवतरण रैखिक इनवोकेशन (~ 30x)।
  4. निष्क्रिय संघनन रेखीय (~ 45x)।

मैंने कभी अनुमान नहीं लगाया था कि पुनरावर्ती कार्य forलूप की तुलना में तेज था : -o

मज़े करो (ctional xD)।


1
पुनरावृत्ति के लिए +1 और स्पष्ट रूप से एक लिस्प हैकर है। मुझे नहीं लगता कि यह इतना अक्षम है या तो, स्ट्रिंग का संघटन युद्ध का समय नहीं है क्योंकि यह एक बार हुआ था, क्योंकि + वास्तव में यह केवल एक स्ट्रिंगबुल्ट यूटीएच है। देखें stackoverflow.com/questions/47605/java-string-concatenation और schneide.wordpress.com/2009/02/23/... । मुझे आश्चर्य है कि पुनरावृत्ति लागत से उन सभी स्टैक को कितना धक्का और चबूतरे, या अगर हॉटस्पॉट उनकी देखभाल करता है। वास्तव में काश मेरे पास इसे बेंचमार्क करने का खाली समय होता। कोई और हो सकता है?
एथन हेइलमैन

@ e5: फोरट्रान सही है; इस समाधान को और अधिक कुशल बनाया जा सकता है। यह कार्यान्वयन अनावश्यक रूप से प्रत्येक पुनरावृत्ति के लिए एक नया स्ट्रिंगबुल्ट (और एक नया स्ट्रिंग) बनाएगा। हालांकि अभी भी एक अच्छा समाधान है।
लूटने

3
@ e5 काश मैं एक लिस्प हैकर xD होता ... अगर मैं होता, तो मैं एक पूंछ पुनरावर्ती कार्य का उपयोग किया होता: --p
फोरट्रान

1
जावा में माइक्रोबेनमार्क अच्छे से काम नहीं करते हैं। अपने कार्यान्वयन की गति को मापने की कोशिश करना ठीक नहीं है।
ceklock

@tecnotron मुझे पता है, लेकिन फिर भी वे कुछ भी नहीं से बेहतर हैं ... और केवल 'आश्चर्य' भोले पाश के संयोजन और रैखिक पुनरावृत्ति के बीच मामूली अंतर था।
फोरट्रान

20

इसमें आपके प्रश्न से कम वर्ण हैं

public static String repeat(String s, int n) {
    if(s == null) {
        return null;
    }
    final StringBuilder sb = new StringBuilder(s.length() * n);
    for(int i = 0; i < n; i++) {
        sb.append(s);
    }
    return sb.toString();
}

4
इसमें मेरे उत्तर StringUtils.repeat (str, n) से अधिक वर्ण हैं।
एथन हेइलमैन

8
जब तक आप पहले से ही अपाचे कॉमन्स का उपयोग नहीं कर रहे हैं, यह उत्तर बहुत कम परेशानी वाला है - कोई अन्य लाइब्रेरी डाउनलोड नहीं करना, जिसमें यह आपके क्लासपाथ में शामिल है, यह सुनिश्चित करना कि इसका लाइसेंस आपके साथ संगत है, आदि
पॉल टॉम्बलिन

7
कृपया, कभी भी अशक्त न लौटें - उस स्थिति में एक रिक्त स्ट्रिंग लौटें, जिससे आप हमेशा अनियंत्रित लौटे मूल्य का उपयोग कर सकें। अन्यथा, मैं पोस्टर का उपयोग करने के लिए क्या सलाह दूंगा।
थोरबजर्न रेवन एंडरसन

7
खैर, अगर एस अशक्त है, तो तीन तरीके हैं। 1. एरर (रिटर्न नल) पास करें, 2. एरर (रिटर्न "") छुपाएं, 3. एनपीई फेंको। त्रुटि को छिपाना और एनपीई को फेंकना अच्छा नहीं है, इसलिए मैंने त्रुटि पारित की।
प्योरोलॉजिकल

1
@ ईथनहिलमैन 2MB का मूल्य जोड़ते हैं commons-lang3.3.1-sourcesऔर आप अब और अच्छे नहीं हैं;) लेकिन अगर किसी के पास पहले से है commons-lang, तो मैं आपके उत्तर का समर्थन करता हूं।
TWiStErRob 20

9

फोरट्रान के उत्तर के आधार पर , यह एक पुनरावर्ती संस्करण है जो स्ट्रिंगब्यूलर का उपयोग करता है:

public static void repeat(StringBuilder stringBuilder, String s, int times) {
    if (times > 0) {
        repeat(stringBuilder.append(s), s, times - 1);
    }
}

public static String repeat(String s, int times) {
    StringBuilder stringBuilder = new StringBuilder(s.length() * times);
    repeat(stringBuilder, s, times);
    return stringBuilder.toString();
}

1
पुनरावृत्ति के बजाय लूपिंग बड़ी संख्या में दोहराव के लिए स्टैक फ्रेम के # कम कर देगा।
ला-कामद्रेजा

7

टाइपिंग के रूप में डॉलर का उपयोग सरल है:

@Test
public void repeatString() {
    String string = "abc";
    assertThat($(string).repeat(3).toString(), is("abcabcabc"));
}

पुनश्च: दोहराने के काम भी सरणी, सूची, सेट, आदि के लिए


3
क्या वास्तव में आवश्यकता है?
ceklock

7

मैं JDBC उद्देश्यों के लिए प्रश्न चिह्नों की अल्पविराम-सीमांकित सूची बनाने के लिए एक फ़ंक्शन चाहता था, और इस पोस्ट को पाया। इसलिए, मैंने दो वेरिएंट लेने का फैसला किया और देखा कि कौन सा बेहतर प्रदर्शन करता है। 1 मिलियन पुनरावृत्तियों के बाद, गार्डन-विविधता StringBuilder ने 2 सेकंड (fun1) लिए, और गुप्त रूप से अधिक इष्टतम संस्करण (fun2) में 30 सेकंड लगे। फिर से क्रिप्टोकरंसी होने की क्या बात है?

private static String fun1(int size) {
    StringBuilder sb = new StringBuilder(size * 2);
    for (int i = 0; i < size; i++) {
        sb.append(",?");
    }
    return sb.substring(1);
}

private static String fun2(int size) {
    return new String(new char[size]).replaceAll("\0", ",?").substring(1);
}

3
मुझे लगता है कि दूसरे को ज्यादा समय लगेगा। यह एक स्ट्रिंग खोज कर रहा है और फिर चरित्र द्वारा स्ट्रिंग चरित्र को संशोधित कर रहा है।
एथन हेइलमैन

7

OOP समाधान

लगभग हर उत्तर एक स्थिर फ़ंक्शन को एक समाधान के रूप में प्रस्तावित करता है, लेकिन ऑब्जेक्ट-ओरिएंटेड (पुन: प्रयोज्यता-उद्देश्यों और स्पष्टता के लिए) के बारे में सोचकर मैं चारसैलेंस-इंटरफ़ेस के माध्यम से डेलिगेशन के माध्यम से एक समाधान के साथ आया (जो कि उत्परिवर्ती चार-असमानता-वर्गों के लिए उपयोगिता भी खोलता है)।

निम्न वर्ग को या तो सेपरेटर-स्ट्रिंग / चारसेंसेंस के साथ या बिना उपयोग किया जा सकता है और प्रत्येक कॉल "toString ()" अंतिम दोहराया स्ट्रिंग का निर्माण करता है। इनपुट / सेपरेटर केवल स्ट्रिंग-क्लास तक ही सीमित नहीं है, बल्कि हर वर्ग हो सकता है जो CharSequence (जैसे StringBuilder, StringBuffer, आदि) को लागू करता है!

सोर्स कोड:

/**
 * Helper-Class for Repeating Strings and other CharSequence-Implementations
 * @author Maciej Schuttkowski
 */
public class RepeatingCharSequence implements CharSequence {
    final int count;
    CharSequence internalCharSeq = "";
    CharSequence separator = "";
    /**
     * CONSTRUCTOR - RepeatingCharSequence
     * @param input CharSequence to repeat
     * @param count Repeat-Count
     */
    public RepeatingCharSequence(CharSequence input, int count) {
        if(count < 0)
            throw new IllegalArgumentException("Can not repeat String \""+input+"\" less than 0 times! count="+count);
        if(count > 0)
            internalCharSeq = input;
        this.count = count;
    }
    /**
     * CONSTRUCTOR - Strings.RepeatingCharSequence
     * @param input CharSequence to repeat
     * @param count Repeat-Count
     * @param separator Separator-Sequence to use
     */
    public RepeatingCharSequence(CharSequence input, int count, CharSequence separator) {
        this(input, count);
        this.separator = separator;
    }

    @Override
    public CharSequence subSequence(int start, int end) {
        checkBounds(start);
        checkBounds(end);
        int subLen = end - start;
        if (subLen < 0) {
            throw new IndexOutOfBoundsException("Illegal subSequence-Length: "+subLen);
        }
        return (start == 0 && end == length()) ? this
                    : toString().substring(start, subLen);
    }
    @Override
    public int length() {
        //We return the total length of our CharSequences with the separator 1 time less than amount of repeats:
        return count < 1 ? 0
                : ( (internalCharSeq.length()*count) + (separator.length()*(count-1)));
    }
    @Override
    public char charAt(int index) {
        final int internalIndex = internalIndex(index);
        //Delegate to Separator-CharSequence or Input-CharSequence depending on internal index:
        if(internalIndex > internalCharSeq.length()-1) {
            return separator.charAt(internalIndex-internalCharSeq.length());
        }
        return internalCharSeq.charAt(internalIndex);
    }
    @Override
    public String toString() {
        return count < 1 ? ""
                : new StringBuilder(this).toString();
    }

    private void checkBounds(int index) {
        if(index < 0 || index >= length())
            throw new IndexOutOfBoundsException("Index out of Bounds: "+index);
    }
    private int internalIndex(int index) {
        // We need to add 1 Separator-Length to total length before dividing,
        // as we subtracted one Separator-Length in "length()"
        return index % ((length()+separator.length())/count);
    }
}

प्रयोग-उदाहरण:

public static void main(String[] args) {
    //String input = "12345";
    //StringBuffer input = new StringBuffer("12345");
    StringBuilder input = new StringBuilder("123");
    //String separator = "<=>";
    StringBuilder separator = new StringBuilder("<=");//.append('>');
    int repeatCount = 2;

    CharSequence repSeq = new RepeatingCharSequence(input, repeatCount, separator);
    String repStr = repSeq.toString();

    System.out.println("Repeat="+repeatCount+"\tSeparator="+separator+"\tInput="+input+"\tLength="+input.length());
    System.out.println("CharSeq:\tLength="+repSeq.length()+"\tVal="+repSeq);
    System.out.println("String :\tLength="+repStr.length()+"\tVal="+repStr);

    //Here comes the Magic with a StringBuilder as Input, as you can append to the String-Builder
    //and at the same Time your Repeating-Sequence's toString()-Method returns the updated String :)
    input.append("ff");
    System.out.println(repSeq);
    //Same can be done with the Separator:
    separator.append("===").append('>');
    System.out.println(repSeq);
}

उदाहरण-आउटपुट:

Repeat=2    Separator=<=    Input=123   Length=3
CharSeq:    Length=8    Val=123<=123
String :    Length=8    Val=123<=123
123ff<=123ff
123ff<====>123ff

4
शायद ही कभी मैंने ऐसी चीजों को देखा है जो घृणित हैं: /
वेन

6

केवल JRE क्लासेस ( System.arraycopy ) का उपयोग करके और कुछ ऐसे अस्थायी ऑब्जेक्ट्स की संख्या को कम करने की कोशिश कर सकते हैं जैसे आप कुछ लिख सकते हैं:

public static String repeat(String toRepeat, int times) {
    if (toRepeat == null) {
        toRepeat = "";
    }

    if (times < 0) {
        times = 0;
    }

    final int length = toRepeat.length();
    final int total = length * times;
    final char[] src = toRepeat.toCharArray();
    char[] dst = new char[total];

    for (int i = 0; i < total; i += length) {
        System.arraycopy(src, 0, dst, i, length);
    }

    return String.copyValueOf(dst);
}

संपादित करें

और बिना छोरों के आप के साथ कोशिश कर सकते हैं:

public static String repeat2(String toRepeat, int times) {
    if (toRepeat == null) {
        toRepeat = "";
    }

    if (times < 0) {
        times = 0;
    }

    String[] copies = new String[times];
    Arrays.fill(copies, toRepeat);
    return Arrays.toString(copies).
              replace("[", "").
              replace("]", "").
              replaceAll(", ", "");
}

EDIT 2

संग्रह का उपयोग करना और भी कम है:

public static String repeat3(String toRepeat, int times) {
    return Collections.nCopies(times, toRepeat).
           toString().
           replace("[", "").
           replace("]", "").
           replaceAll(", ", "");
}

हालाँकि मुझे अभी भी पहला संस्करण पसंद है।


6
-1: आधे से बहुत चालाक। यदि आपका उद्देश्य आपको कोड को पठनीय या कुशल बनाना है, तो ये "समाधान" एक अच्छा विचार नहीं है। could रिपीट ’को एक स्ट्रिंगबर्ल (प्रारंभिक क्षमता स्थापित करने) का उपयोग करके फिर से लिखा जा सकता है। और 'repeat2' / 'repeat3' वास्तव में अक्षम हैं, और स्ट्रिंग [] .String () द्वारा निर्मित स्ट्रिंग के अनिर्दिष्ट वाक्यविन्यास पर निर्भर करते हैं।
स्टीफन सी

@ थोरब: बिल्कुल, इस कोड के साथ आप "मेटाचेचर" का उपयोग नहीं कर सकते, [],
dfa

@Stephen: इस प्रश्न का स्पष्ट रूप से कोई लूप अनुरोध करने के लिए संपादित नहीं किया गया था । StringBuilder आधारित उत्तर पहले से ही प्रदान किया गया था इसलिए मैंने एक डुप्लिकेट पोस्ट करने से परहेज किया
dfa

@ स्टेफ़न: मैं डाउनवोट का पता नहीं लगा सकता। मेरे संपादित उत्तर को लूप-फ्री कहा गया है। दक्षता के बारे में कोई अनुरोध नहीं हैं। मुझे लगता है कि यह सवाल सिर्फ एक बौद्धिक प्रयास है कि एक पाश के बिना एक संगति पैदा की जाए।
dfa

@Stephan: Collection.toString (और Arrays.toString) के माध्यम से उत्पादित स्ट्रिंग AbstractCollection.toString में स्पष्ट रूप से निर्दिष्ट है: "स्ट्रिंग प्रतिनिधित्व संग्रह के तत्वों की एक सूची के क्रम में होते हैं, जो वे इसके इट्रेटर में वापस आ गए हैं, जो वर्ग कोष्ठक में संलग्न हैं ( "[]")। आसन्न तत्वों को पात्रों द्वारा अलग किया जाता है "," (अल्पविराम और स्थान)। "
dfa

6

सबसे छोटा नहीं है, लेकिन (मुझे लगता है) सबसे तेज़ तरीका है स्ट्रिंगब्यूलर का उपयोग करना:

 /**
   * Repeat a String as many times you need.
   *
   * @param i - Number of Repeating the String.
   * @param s - The String wich you want repeated.
   * @return The string n - times.
   */
  public static String repeate(int i, String s) {
    StringBuilder sb = new StringBuilder();
    for (int j = 0; j < i; j++)
      sb.append(s);
    return sb.toString();
  }

5

यदि गति आपकी चिंता है, तो आपको यथासंभव कम मेमोरी कॉपी का उपयोग करना चाहिए। इस प्रकार वर्णों के सरणियों के साथ काम करना आवश्यक है।

public static String repeatString(String what, int howmany) {
    char[] pattern = what.toCharArray();
    char[] res = new char[howmany * pattern.length];
    int length = pattern.length;
    for (int i = 0; i < howmany; i++)
        System.arraycopy(pattern, 0, res, i * length, length);
    return new String(res);
}

गति का परीक्षण करने के लिए, StirngBuilder का उपयोग करने वाली एक समान इष्टतम विधि इस प्रकार है:

public static String repeatStringSB(String what, int howmany) {
    StringBuilder out = new StringBuilder(what.length() * howmany);
    for (int i = 0; i < howmany; i++)
        out.append(what);
    return out.toString();
}

और यह परीक्षण करने के लिए कोड:

public static void main(String... args) {
    String res;
    long time;

    for (int j = 0; j < 1000; j++) {
        res = repeatString("123", 100000);
        res = repeatStringSB("123", 100000);
    }

    time = System.nanoTime();
    res = repeatString("123", 1000000);
    time = System.nanoTime() - time;
    System.out.println("elapsed repeatString: " + time);

    time = System.nanoTime();
    res = repeatStringSB("123", 1000000);
    time = System.nanoTime() - time;
    System.out.println("elapsed repeatStringSB: " + time);

}

और यहाँ मेरे सिस्टम से रन परिणाम:

elapsed repeatString: 6006571
elapsed repeatStringSB: 9064937

ध्यान दें कि लूप के लिए परीक्षण JIT में किक करना है और इसके इष्टतम परिणाम हैं।



3

यदि आप प्रदर्शन के बारे में चिंतित हैं, तो बस लूप के अंदर एक स्ट्रिंगबर्ल का उपयोग करें और लूप से बाहर निकलने पर एक .toString () करें। हेक, अपना खुद का यूटील क्लास लिखिए और उसका पुनः उपयोग करें। कोड अधिकतम की 5 लाइनें।


2

मैं वास्तव में इस सवाल का आनंद लेता हूं। ज्ञान और शैलियों का एक बहुत कुछ है। इसलिए मैं इसे अपनी रॉक एंड रोल दिखाए बिना नहीं छोड़ सकता;)

{
    String string = repeat("1234567890", 4);
    System.out.println(string);
    System.out.println("=======");
    repeatWithoutCopySample(string, 100000);
    System.out.println(string);// This take time, try it without printing
    System.out.println(string.length());
}

/**
 * The core of the task.
 */
@SuppressWarnings("AssignmentToMethodParameter")
public static char[] repeat(char[] sample, int times) {
    char[] r = new char[sample.length * times];
    while (--times > -1) {
        System.arraycopy(sample, 0, r, times * sample.length, sample.length);
    }
    return r;
}

/**
 * Java classic style.
 */
public static String repeat(String sample, int times) {
    return new String(repeat(sample.toCharArray(), times));
}

/**
 * Java extreme memory style.
 */
@SuppressWarnings("UseSpecificCatch")
public static void repeatWithoutCopySample(String sample, int times) {
    try {
        Field valueStringField = String.class.getDeclaredField("value");
        valueStringField.setAccessible(true);
        valueStringField.set(sample, repeat((char[]) valueStringField.get(sample), times));
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

क्या आपको यह पसंद है?


1
मेरे अधिक चरम परीक्षण में, मैं 1,700,000,000 (1.7 गिगास) स्ट्रिंग रिपीट लंबाई का उपयोग करता हूं, -Xms4937m का उपयोग करके
डैनियल डे लियोन

2
public static String repeat(String str, int times) {
    int length = str.length();
    int size = length * times;
    char[] c = new char[size];
    for (int i = 0; i < size; i++) {
        c[i] = str.charAt(i % length);
    }
    return new String(c);
}

2

साधारण लूप

public static String repeat(String string, int times) {
    StringBuilder out = new StringBuilder();
    while (times-- > 0) {
        out.append(string);
    }
    return out.toString();
}

2
timesStringBuilder कंस्ट्रक्टर के पास ।
बेह्रोज़।

2

इसे आज़माएं:

public static char[] myABCs = {'a', 'b', 'c'};
public static int numInput;
static Scanner in = new Scanner(System.in);

public static void main(String[] args) {
    System.out.print("Enter Number of Times to repeat: ");
    numInput = in.nextInt();
    repeatArray(numInput);
}

public static int repeatArray(int y) {
    for (int a = 0; a < y; a++) {
        for (int b = 0; b < myABCs.length; b++) {
            System.out.print(myABCs[b]);                
        }
        System.out.print(" ");
    }
    return y;
}

2

पुनरावर्तन का उपयोग करके, आप निम्न कार्य कर सकते हैं (टर्नरी ऑपरेटरों का उपयोग करते हुए, एक पंक्ति अधिकतम):

public static final String repeat(String string, long number) {
    return number == 1 ? string : (number % 2 == 0 ? repeat(string + string, number / 2) : string + repeat(string + string, (number - 1) / 2));
}

मुझे पता है, यह बदसूरत है और शायद कुशल नहीं है, लेकिन यह एक पंक्ति है!


यह वह तरीका है जो मैं ले जाऊंगा लेकिन जरूरत से ज्यादा जांच क्यों करूं? वापसी संख्या> 0? स्ट्रिंग + दोहराना (स्ट्रिंग, संख्या -1): "";
फेयरिंग

ओह, नीचे इसके साथ जवाब niczm25 लगता है
fering

@ मुख्य कारण यह है कि यह रास्ता हमेशा O (N) के बजाय O (लॉग एन) औसत है। एक दूसरे की तुलना में थोड़ा अधिक अनुकूलन, हालांकि अभी भी बुरा है।
HyperNeutrino

2

एक सीधा एक-लाइन समाधान:
जावा 8 की आवश्यकता है

Collections.nCopies( 3, "abc" ).stream().collect( Collectors.joining() );

1

लूप्स का उपयोग न करने की आपकी इच्छा के बावजूद, मुझे लगता है कि आपको लूप का उपयोग करना चाहिए।

String repeatString(String s, int repetitions)
{
    if(repetitions < 0) throw SomeException();

    else if(s == null) return null;

    StringBuilder stringBuilder = new StringBuilder(s.length() * repetitions);

    for(int i = 0; i < repetitions; i++)
        stringBuilder.append(s);

    return stringBuilder.toString();
}

लूप के लिए उपयोग नहीं करने के आपके कारण अच्छे नहीं हैं। अपनी आलोचनाओं के जवाब में:

  1. जो भी समाधान आप उपयोग करते हैं वह निश्चित रूप से इससे अधिक लंबा होगा। पूर्व-निर्मित फ़ंक्शन का उपयोग करना केवल इसे अधिक कवर के तहत टक करता है।
  2. आपके कोड को पढ़ने वाले किसी व्यक्ति को यह पता लगाना होगा कि आप उस गैर-लूप में क्या कर रहे हैं। यह देखते हुए कि एक फॉर-लूप ऐसा करने का मुहावरेदार तरीका है, यदि आपने लूप के लिए यह किया है, तो यह पता लगाना बहुत आसान होगा।
  3. हां, कोई व्यक्ति कुछ चतुर जोड़ सकता है, लेकिन लूप से बचने के लिए आप कुछ चतुर कर रहे हैं । यह अपने आप को दुर्घटना से पैर में शूटिंग से बचने के लिए जानबूझकर पैर में गोली मारने जैसा है।
  4. एक-एक परीक्षा के साथ ऑफ-द-वन त्रुटियां भी आसानी से दिमाग में आ जाती हैं। यह देखते हुए कि आपको अपने कोड का परीक्षण करना चाहिए, एक ऑफ-बाय-वन त्रुटि को ठीक करना और पकड़ना आसान होना चाहिए। और यह ध्यान देने योग्य है: ऊपर दिए गए कोड में ऑफ-बाय-वन त्रुटि नहीं है। छोरों के लिए सही होने के लिए समान रूप से आसान है।
  5. तो चर का पुन: उपयोग न करें। यह लूप की गलती नहीं है।
  6. फिर से, जो भी समाधान आप उपयोग करते हैं। और जैसा कि मैंने पहले उल्लेख किया था; एक बग शिकारी संभवतः आपको लूप के लिए ऐसा करने की उम्मीद कर रहा होगा, इसलिए यदि आप लूप के लिए उपयोग करते हैं तो उनके पास इसे ढूंढने का एक आसान समय होगा।

3
-1। यहां आपके लिए दो अभ्यास हैं: ए) के साथ अपना कोड चलाएं repetitions = -5। बी) कॉमन्स लैंग को डाउनलोड करें और repeatString('a', 1000)एक लूप में एक लाख बार चलाएं ; अपने कोड के साथ भी ऐसा ही करें; समय की तुलना करें। अतिरिक्त क्रेडिट के लिए भी ऐसा ही करें repeatString('ab', 1000)
ChssPly76

2
क्या आप तर्क दे रहे हैं कि आपका कोड अधिक पठनीय है StringUtils.repeat("ab",1000)? क्योंकि यह मेरा जवाब था कि आपने नीचे लिखा है। यह बेहतर प्रदर्शन भी करता है और इसमें कोई बग नहीं है।
ChssPly76

2
जिस प्रश्न को आप उद्धृत कर रहे हैं, उसमें दूसरा वाक्य पढ़ें। "मैं हर कीमत पर छोरों से बचने की कोशिश करता हूं क्योंकि" मेरे जवाब के बाद एंड्रयू हरे के जवाब के जवाब में एक स्पष्टीकरण के रूप में सवाल में जोड़ा गया था - यह नहीं कि यह मायने रखता है क्योंकि अगर आप जिस स्थिति में हैं, वह है "जवाब खराब है अगर लूप है कहीं भी उपयोग किया जाता है "ओपी प्रश्न के उत्तर नहीं हैं। यहां तक ​​कि dfa के समाधान - जैसा कि वे हैं - आविष्कारशील - अंदर छोरों के लिए उपयोग करें। "जार नरक" को ऊपर जवाब दिया गया था; कॉमन्स लैंग वैसे भी हर सभ्य-आकार के अनुप्रयोग में उपयोग किया जाता है और इस तरह एक नई निर्भरता नहीं जोड़ता है।
ChssPly76

2
@ ChssPly76 इस बिंदु पर मुझे यकीन है कि कल्पना ट्रोलिंग है। मेरे पास वास्तव में एक कठिन समय है कि कोई भी कैसे पढ़ सकता है जो मैंने लिखा है और गंभीरता से लगता है कि ऊपर टाइप की गई प्रतिक्रियाएं।
एथन हेइल्मन

1
@ ChssPly76 मेरे जवाब में कोई लूप नहीं है :-p
फोरट्रान

1

यदि आप केवल आउटपुट स्ट्रिंग की लंबाई जानते हैं (और यह इनपुट स्ट्रिंग की लंबाई से विभाज्य नहीं हो सकती है), तो इस विकल्प का उपयोग करें:

static String repeat(String s, int length) {
    return s.length() >= length ? s.substring(0, length) : repeat(s + s, length);
}

उपयोग डेमो:

for (int i = 0; i < 50; i++)
    System.out.println(repeat("_/‾\\", i));

खाली sऔर length> 0 के साथ प्रयोग न करें , क्योंकि इस मामले में वांछित परिणाम प्राप्त करना असंभव है।


0

यहाँ नवीनतम Stringutils.java है StringUtils.java

    public static String repeat(String str, int repeat) {
    // Performance tuned for 2.0 (JDK1.4)

    if (str == null) {
        return null;
    }
    if (repeat <= 0) {
        return EMPTY;
    }
    int inputLength = str.length();
    if (repeat == 1 || inputLength == 0) {
        return str;
    }
    if (inputLength == 1 && repeat <= PAD_LIMIT) {
        return repeat(str.charAt(0), repeat);
    }

    int outputLength = inputLength * repeat;
    switch (inputLength) {
        case 1 :
            return repeat(str.charAt(0), repeat);
        case 2 :
            char ch0 = str.charAt(0);
            char ch1 = str.charAt(1);
            char[] output2 = new char[outputLength];
            for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
                output2[i] = ch0;
                output2[i + 1] = ch1;
            }
            return new String(output2);
        default :
            StringBuilder buf = new StringBuilder(outputLength);
            for (int i = 0; i < repeat; i++) {
                buf.append(str);
            }
            return buf.toString();
    }
    }

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

    public static String repeat(String str, int num) {
    int len = num * str.length();
    StringBuilder sb = new StringBuilder(len);
    for (int i = 0; i < times; i++) {
        sb.append(str);
    }
    return sb.toString();
    }

इसलिए e5, मुझे लगता है कि ऐसा करने का सबसे अच्छा तरीका केवल उपर्युक्त कोड का उपयोग करना होगा, या यहां किसी भी उत्तर का होगा। लेकिन अगर यह एक छोटा प्रोजेक्ट है तो कॉमन्स लैंग बहुत बड़ा है


मुझे नहीं लगता कि वहाँ बहुत कुछ है जो आप कर सकते हैं ... एक्सैट शायद एक एओटी !!
एलेम्हर्रमन

0

मैंने एक पुनरावर्ती विधि बनाई जो आप चाहते हैं वही काम करें .. इस का उपयोग करने के लिए स्वतंत्र महसूस करें ...

public String repeat(String str, int count) {
    return count > 0 ?  repeat(str, count -1) + str: "";
}

क्या मेरे पास एक ही उत्तर है कि क्या मैं दृश्यों को दोहराने के लिए जावा में स्ट्रिंग्स को गुणा कर सकता हूं?


अनावश्यक स्ट्रिंग वसूली, और पुनरावृत्ति उपरि ... बुरा, बुरा, अच्छा नहीं।
अलेक्जेंडर -

1
यह धीमा होगा। सिफारिश नहीं की गई! StringBuilderइसके बजाय उपयोग करें ।
स्वेतलिन नाकोव

0
public static String rep(int a,String k)

       {
           if(a<=0)
                return "";
           else 
           {a--;
               return k+rep(a,k);
       }

आप अपने इच्छित लक्ष्य के लिए इस पुनरावर्ती विधि का उपयोग कर सकते हैं।

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