วิธีง่ายๆในการทำซ้ำสตริงใน java


597

ฉันกำลังมองหาวิธีการทั่วไปหรือผู้ประกอบการที่ช่วยให้ฉันสามารถทำซ้ำสตริงnบางครั้ง ฉันรู้ว่าฉันสามารถเขียนสิ่งนี้โดยใช้ for for loop แต่ฉันต้องการหลีกเลี่ยงการวนซ้ำเมื่อจำเป็น

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

repeated.equals("abcabcabc");

ที่เกี่ยวข้องกับ:

javascript สตริงซ้ำ สร้าง NSString โดยทำซ้ำสตริงอื่นตามจำนวนครั้งที่กำหนด

แก้ไข

ฉันพยายามหลีกเลี่ยงลูปเมื่อไม่จำเป็นอย่างสมบูรณ์เพราะ:

  1. พวกเขาเพิ่มจำนวนบรรทัดของรหัสแม้ว่าพวกเขาจะซุกอยู่ในฟังก์ชันอื่น

  2. ใครบางคนกำลังอ่านโค้ดของฉันจะต้องเข้าใจว่าฉันกำลังทำอะไรอยู่ แม้ว่าจะได้รับการแสดงความคิดเห็นและมีชื่อตัวแปรที่มีความหมายพวกเขายังคงต้องตรวจสอบให้แน่ใจว่าไม่ได้ทำอะไร "ฉลาด"

  3. โปรแกรมเมอร์ชอบที่จะใส่สิ่งที่ฉลาดในการวนรอบแม้ว่าฉันจะเขียนถึง "ทำในสิ่งที่ตั้งใจทำเท่านั้น" นั่นไม่ได้ขัดขวางคนที่เข้ามาและเพิ่ม "แก้ไข" ที่ชาญฉลาดเพิ่มเติม

  4. พวกเขามักจะผิดพลาดได้ง่ายมาก สำหรับลูปที่เกี่ยวข้องกับดัชนีมักจะเกิดจากข้อบกพร่องหนึ่งข้อ

  5. สำหรับลูปมักจะนำตัวแปรเดิมมาใช้ซ้ำซึ่งเป็นการเพิ่มโอกาสในการหาข้อบกพร่องที่กำหนดขอบเขตได้ยากมาก

  6. สำหรับลูปเพิ่มจำนวนสถานที่ที่นักล่าบั๊กต้องดู


35
ฉันเข้าใจว่าสำหรับลูปอาจทำให้เกิดปัญหาจริงได้ แต่คุณไม่ควรพยายามหลีกเลี่ยงลูป "ที่ค่าใช้จ่ายทั้งหมด" เพราะถ้ามันมีค่าใช้จ่ายคุณสามารถอ่านได้การบำรุงรักษาและความเร็วคุณกำลังต่อต้าน นี่เป็นหนึ่งในกรณีเหล่านั้น
Imagist

9
"พวกมันเพิ่มจำนวนบรรทัดของรหัสแม้ว่าพวกมันจะถูกซ่อนอยู่ในฟังก์ชั่นอื่น" ... ว้าวแค่ว้าว Big-O ไม่ใช่ LoC
Pyrolistical

7
@ ช่างภาพฉันหลีกเลี่ยงการวนซ้ำในสถานการณ์ที่ทำให้ฉันเสียค่าใช้จ่ายในการอ่านและการบำรุงรักษา ฉันถือว่าความเร็วเป็นปัญหาที่สำคัญที่สุดที่นี่ (ไม่ใช่ปัญหาจริง) ฉันคิดว่าลูปมีการใช้งานมากเกินไปและฉันพยายามที่จะเรียนรู้ที่จะใช้ลูปเมื่อจำเป็นเท่านั้นไม่ใช่วิธีแก้ปัญหาเริ่มต้น
Ethan Heilman

3
@ ไพเราะจิปาถะฉันไม่ได้อ้างสิทธิ์ในการปฏิบัติงานหรือผลประโยชน์เชิงซีมโทติค แทนที่จะบอกว่าโดยการเขียนโค้ดให้น้อยลงและการใช้ฟังก์ชั่นห้องสมุดมากกว่าการปรับแต่งวงล้อฉันจะลดพื้นที่ผิวของบั๊ก (Lines of Code) ในขณะที่เพิ่มความสามารถในการอ่าน ทั้งสองสิ่งที่ดีฉันแน่ใจว่าคุณจะเห็นด้วย
Ethan Heilman

4
@ e5; ขออภัยสำหรับการโพสต์ปีต่อมาฉันพบคำถามนี้เหมาะสม หากแทรกในเมธอดอาร์กิวเมนต์ควรถูกทดสอบ (ครั้ง> = 0) ข้อผิดพลาดที่เกิดขึ้น ฯลฯ ซึ่งจะเพิ่มความทนทาน แต่ยังมีบรรทัดของรหัสที่จะอ่าน การทำซ้ำสตริงเป็นสิ่งที่ไม่คลุมเครือผู้อ่านรหัสรู้ว่าสิ่งที่ string ทำซ้ำแม้ไม่มีความคิดเห็นหรือ javadoc หากเราใช้ไลบรารีที่มีความเสถียรก็มีเหตุผลที่จะคิดว่าฟังก์ชั่นที่เรียบง่ายไม่มีข้อบกพร่อง YET ขอแนะนำรูปแบบการตรวจสอบ "ความทนทาน" ที่เราจำเป็นต้องกังวลด้วยหากฉันสามารถขอให้ปรับปรุงได้ 10 ข้อสิ่งต่าง ๆ นี้จะเป็นอย่างใดอย่างหนึ่ง
AgostinoX

คำตอบ:


229

String::repeat

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

ใหม่ใน Java 11เป็นวิธีการString::repeatที่ตรงตามที่คุณขอ:

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

Javadocมันพูดว่า:

/**
 * 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
ฉันยังไม่เคยเห็น java 9ยังอยู่บนถนน (และจะไม่เป็นเวลานาน .. ) - และ11ถูกตั้งค่าให้จัดส่ง ..
javadba

1
เห็นได้ชัดอาจเป็นไปได้ แต่คุณสามารถเรียกใช้วิธีนี้ในสายอักขระตามตัวอักษรได้เช่นกัน:"abc".repeat(3)
27432

895

นี่คือเวอร์ชันที่สั้นที่สุด (จำเป็นต้องใช้ Java 1.5+):

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

ที่ไหนnคือจำนวนครั้งที่คุณต้องการที่จะทำซ้ำสตริงและsเป็นสตริงที่ซ้ำ

ไม่ต้องนำเข้าหรือไลบรารี


22
ฉันไม่คิดว่ามันจะทำให้งงงวยเลย ประเภทดั้งเดิม ( char[]ในกรณีนี้) จะถูกสร้างอินสแตนซ์ด้วย nulls จากนั้น a Stringถูกสร้างขึ้นจากchar[]และ null จะอยู่replaced()กับตัวละครที่คุณต้องการs
Amarok

32
ในขณะนี้เป็นสิ่งที่ฉลาดมาก (+1) ฉันคิดว่ามันค่อนข้างพิสูจน์ได้ว่าจุดสำหรับลูปมักจะทำเพื่อให้ได้รหัสที่ชัดเจน
Richard Tingle

75
สำหรับผู้ที่บ่นเรื่องความงงงวยการอ่านจะขึ้นอยู่กับความรู้ นี่คือสิ่งที่ชัดเจนอย่างสมบูรณ์ในสิ่งที่มันทำและการศึกษาสำหรับผู้ที่อาจไม่เห็นมันในทันที นี่คือสิ่งที่คุณได้รับจาก Java โดยวิธี
dansalmo

11
เพื่อประสิทธิภาพที่ดีขึ้น...replace('\0', str)ควรใช้แทนรุ่น String
user686249

11
@ user686249: มีเพียงreplace(char oldChar, char newChar)และreplace(CharSequence target, CharSequence replacement)ดังนั้นผมจึงไม่เห็นวิธีการที่สามารถทำงาน
user102008

334

หากคุณใช้Java <= 7นี่จะเป็น "รัดกุม" ตามที่ได้รับ:

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

ในJava 8ขึ้นไปมีวิธีที่อ่านง่ายกว่า:

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

ในที่สุดสำหรับJava 11และสูงกว่ามีrepeat​(int count)วิธีการใหม่โดยเฉพาะสำหรับเรื่องนี้ ( ลิงค์ )

"abc".repeat(12);

อีกทางหนึ่งถ้าโครงการของคุณใช้ไลบรารี java มีตัวเลือกเพิ่มเติม

สำหรับApache Commons :

StringUtils.repeat("abc", 12);

สำหรับGoogle Guava :

Strings.repeat("abc", 12);

4
อดีตทำให้เกิดข้อยกเว้นเมื่อnเป็นศูนย์
saka1029

ตัวอย่าง java 8 ไม่ได้คอมไพล์ -> Type mismatch: ไม่สามารถแปลงจาก List <Character> เป็น CharSequence
Arigion

6
@Arigion sต้องเป็น String ไม่ใช่Char
Caner

@Caner ขอบคุณ ฉันไม่ดีฉันขอโทษ เห็นได้ชัดว่าเมื่อวานฉันเหนื่อยเกินไป ขออภัยเกี่ยวกับ downvoting ฉันจะลบ downvote โดยเร็วที่สุดเท่าที่จะทำได้ (มันถูกปิดกั้นจนกว่าคำถามจะได้รับการแก้ไข)
Arigion

@ Arigion ไม่มีปัญหาทำให้ชัดเจนแล้วว่าเป็นสตริง
Caner

312

คอมมอนส์ Lang StringUtils.repeat ()

การใช้งาน:

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

repeated.equals("abcabcabc");

99
การใช้การพึ่งพาวิธีเดียวเพื่อเห็นแก่ความเรียบง่ายในระยะยาวอาจส่งผลให้เกิดนรก
dfa

81
แน่นอนยกเว้นว่าเป็นภาษาทั่วไป ฉันไม่คิดว่าฉันเคยเห็นโครงการมากกว่า 5,000 LOCS ที่ไม่มีคอมมอนส์
Ethan Heilman

11
คอมมอนส์หรั่งเป็นโอเพนซอร์ส - ดาวน์โหลดและดู แน่นอนว่ามันมีลูปด้านใน แต่ก็ไม่ง่ายนัก ความพยายามอย่างมากในการทำโปรไฟล์และทำให้การใช้งานนั้นมีประสิทธิภาพสูงสุด
ChssPly76

28
ฉันไม่หลีกเลี่ยงการวนซ้ำด้วยเหตุผลด้านประสิทธิภาพ (อ่านเหตุผลในคำถาม) เมื่อมีคนเห็น StringUtils.repeat พวกเขารู้ว่าฉันกำลังทำอะไรอยู่ พวกเขาไม่ต้องกังวลว่าฉันพยายามเขียนเวอร์ชันการทำซ้ำของตัวเองและทำผิดพลาด มันเป็นหน่วยความรู้เกี่ยวกับอะตอม!
Ethan Heilman

7
@ Thorbjørn Ravn Andersen - มันสามารถได้รับมากน่าสนใจมากขึ้นถ้าสิ่งที่ให้ถูกนำออกไปจากบริบท
ChssPly76

140

Java 8's String.joinจัดเตรียมวิธีที่เป็นระเบียบเรียบร้อยในการดำเนินการร่วมกับCollections.nCopies:

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

7
ขอบคุณ! สำหรับ android TextUtils.join () สามารถนำมาใช้แทน String.join ()
MinaHany

2
ขอบคุณสำหรับคำตอบนี้ ดูเหมือนว่าจะเป็นวิธีที่สะอาดที่สุดโดยไม่ต้องใช้วิธีการอื่น ๆ ของ API อื่น ๆ ! ดีมาก!!
Andreas M. Oberheim

2
สิ่งที่ดีเกี่ยวกับวิธีการนี้คือเมื่อคุณเข้าร่วมคุณสามารถระบุตัวคั่นที่ใช้งานได้ดีถ้าคุณพูดสร้างรายการ CSV ด้วยวิธีการอื่น ๆ ทั้งหมดคุณจะต้องยกเลิกอักขระการเข้าร่วมที่ต้องแยกออกจากกันในการดำเนินการแยกต่างหาก
DroidOS

102

ต่อไปนี้เป็นวิธีการใช้ฟังก์ชั่น String มาตรฐานเท่านั้นและไม่มีการวนซ้ำอย่างชัดเจน:

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

5
น่าทึ่ง :-) ถึงแม้ว่าจะไม่ได้เป็นศูนย์ ... !
Yang Meyer

4
@Vijay Dev และ Fortran: replace()ไม่มีเขาหมายถึง ใน Java 1.5+ มีรุ่นreplace()ที่ใช้งานมากเกินไปซึ่งใช้เวลาสองCharSequenceวินาที (ซึ่งรวมถึงString): download.oracle.com/javase/1.5.0/docs/api/java/lang/…
user102008

79
อุ๊ยตาย นี่มันน่าเกลียด
Karel Bílek

8
@mzuba สมมติว่าn=3: ก่อนอื่นให้จัดรูปแบบสตริงเพื่อให้มีลักษณะดังนี้%03d( %%คือการหลีกเลี่ยงเครื่องหมายเปอร์เซ็นต์) ซึ่งเป็นรหัสการจัดรูปแบบเพื่อเพิ่มศูนย์ padding 3 จากนั้นจัดรูปแบบ0ด้วยสิ่งนั้นนำไปสู่000และสุดท้ายแทนที่แต่ละ0สตริงด้วย
fortran

15
คุณสามารถทำให้การแก้ปัญหาน่าเกลียดน้อยลงและเข้าใจง่ายขึ้น: String.format ("% 0" + n + "d", 0) .replace ("0", s)
Artur

87

หากคุณชอบฉันและต้องการใช้ Google Guava ไม่ใช่ Apache Commons คุณสามารถใช้วิธีการซ้ำในคลาส Guava Strings

Strings.repeat("-", 60);

2
... และรับ 3Mb จากการอ้างอิงใหม่
MonoThreaded

6
@ โมโหด้ายฉันคิดว่ามันจะไปโดยไม่บอก แต่ไม่รวมฝรั่งเพื่อทำซ้ำสตริง คำตอบของฉันเกี่ยวกับถ้าคุณใช้ฝรั่งอยู่แล้วนี่เป็นวิธีที่คุณทำ
แจ็ค

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)

คุณต้องการให้เรียบง่ายและสวยกว่ากัน? ใช้ jython:

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

แก้ไข 2 : ฉันทำเกณฑ์มาตรฐานที่รวดเร็วและสกปรกสำหรับตัวเลือกหลัก 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 ข้อโต้แย้งข้อแรกคือจำนวนการวนซ้ำ (แต่ละฟังก์ชั่นทำงานโดยมีเวลาทำซ้ำ arg จาก 1..n) และที่สองคือสตริงที่จะทำซ้ำ

จนถึงตอนนี้การตรวจสอบอย่างรวดเร็วของเวลาที่ทำงานด้วยอินพุตที่แตกต่างกันทำให้การจัดอันดับเป็นแบบนี้ (ดีกว่าแย่กว่า):

  1. เพิ่มซ้ำ StringBuilder ผนวก (1x)
  2. การเชื่อมต่อแบบเรียกซ้ำการล็อกแบบเรียกซ้ำ (~ 3x)
  3. การเชื่อมโยงการเรียกซ้ำเชิงซ้อนแบบเรียกซ้ำ (~ 30x)
  4. การต่อข้อมูลแบบวนซ้ำเชิงเส้น (~ 45x)

ฉันไม่เคยเดาเลยว่าฟังก์ชั่นวนซ้ำนั้นเร็วกว่าforลูป: -o

ขอให้สนุก (ctional xD)


1
+1 สำหรับการเรียกซ้ำและเห็นได้ชัดว่าเป็นแฮ็กเกอร์เสียงกระเพื่อม ฉันไม่คิดว่ามันจะไร้ประสิทธิภาพเช่นกันการต่อสายอักขระไม่ใช่สงครามครั้งก่อนเพราะ + จริงๆแล้วเป็นเพียงแค่ stringBuilder UTH ดูstackoverflow.com/questions/47605/java-string-concatenation และ schneide.wordpress.com/2009/02/23/... ฉันสงสัยว่าสแต็กเหล่านั้นจะผลักและโผล่ออกมาจากต้นทุนการเรียกซ้ำจำนวนเท่าใดหรือถ้าฮอตสปอตดูแลพวกเขา หวังว่าฉันจะมีเวลาว่างในการเปรียบเทียบ มีคนอื่นอาจจะ?
Ethan Heilman

@ e5: fortran ถูกต้อง; วิธีนี้สามารถทำให้มีประสิทธิภาพมากขึ้น การใช้งานนี้จะสร้าง StringBuilder ใหม่ (และสตริงใหม่) โดยไม่จำเป็นสำหรับการเรียกซ้ำแต่ละครั้ง ยังคงเป็นทางออกที่ดีแม้ว่า
ปล้น

3
@ e5 ฉันหวังว่าฉันจะเป็นแฮ็กเกอร์ Lisp xD ... ถ้าฉันเป็นฉันจะใช้ฟังก์ชั่นเรียกซ้ำ :-p
fortran

1
Microbenchmarks ทำงานได้ไม่ดีใน Java พยายามวัดความเร็วของการติดตั้งใช้งานของคุณแบบนั้นไม่ดี
ceklock

@ เทคโนทรอนฉันรู้ แต่พวกเขาก็ยังดีกว่าไม่มีอะไร ... และ 'เซอร์ไพร์ส' เดียวเท่านั้นคือความแตกต่างเล็กน้อยระหว่างการต่อเชื่อมลูปที่ไร้เดียงสากับการเรียกซ้ำเชิงเส้น
fortran

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)
Ethan Heilman

8
ถ้าคุณไม่ใช้ Apache Commons อยู่แล้วคำตอบนี้จะยุ่งยากน้อยลง - ไม่มีการดาวน์โหลดไลบรารี่อื่นรวมถึงไลบรารี่ใน classpath ของคุณ
Paul Tomblin

7
โปรดอย่าคืนค่าว่างในกรณีนี้คืนสตริงว่างเปล่าให้คุณใช้ค่าที่ส่งคืนโดยไม่เลือก มิฉะนั้นสิ่งที่ฉันอยากจะแนะนำให้ใช้โปสเตอร์
Thorbjørn Ravn Andersen

7
มีสามวิธีในการจัดการถ้า s เป็นโมฆะ 1. ผ่านข้อผิดพลาด (return null), 2. ซ่อนข้อผิดพลาด (return ""), 3. โยน NPE การซ่อนข้อผิดพลาดและการขว้าง NPE นั้นไม่เย็นฉันเลยส่งข้อผิดพลาด
Pyrolistical

1
@EthanHeilman เพิ่มมูลค่า 2MB commons-lang3.3.1-sourcesและคุณไม่ดีอีกต่อไป;) แต่ถ้ามีคนอยู่แล้วcommons-langฉันสนับสนุนคำตอบของคุณ
TWiStErRob

9

ตามคำตอบของ fortranนี่เป็นเวอร์ชั่นที่ใช้ซ้ำได้ซึ่งใช้ StringBuilder:

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
การวนซ้ำมากกว่าการเรียกซ้ำจะช่วยลด # ของเฟรมสแต็กสำหรับการทำซ้ำจำนวนมาก
La-comadreja

7

การใช้Dollarนั้นง่ายเหมือนการพิมพ์:

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

PS: ทำงานซ้ำสำหรับอาร์เรย์, รายการ, ชุด, ฯลฯ


3
assertThat () เป็นวิธีการที่จำเป็นจริงๆ?
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
ฉันเข้าใจว่าอันที่สองจะใช้เวลานานกว่ามาก มันกำลังดำเนินการค้นหาสตริงและจากนั้นปรับเปลี่ยนอักขระสตริงโดยตัวละคร
Ethan Heilman

7

โซลูชัน OOP

เกือบทุกคำตอบเสนอฟังก์ชั่นแบบคงที่เป็นวิธีแก้ปัญหา แต่คิดว่า Object-Oriented (เพื่อนำมาใช้ใหม่ได้และมีความชัดเจน) ฉันมาพร้อมกับโซลูชันผ่านการมอบหมายผ่าน CharSequence-Interface (ซึ่งเปิดใช้งาน CharSequence-Classes

Class ต่อไปนี้สามารถใช้ได้ทั้งแบบมีหรือไม่มี Separator-String / CharSequence และการเรียกแต่ละครั้งไปที่ "toString ()" จะสร้างสตริงที่ซ้ำกันครั้งสุดท้าย Input / Separator ไม่เพียง แต่ถูก จำกัด ให้ใช้งานกับ String-Class เท่านั้น แต่ยังสามารถเป็น Class ทุกคลาสที่ใช้ 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
ไม่ค่อยได้ผมเห็นสิ่งที่น่าขยะแขยง: /
Ven

6

ใช้คลาส JRE เท่านั้น ( System.arraycopy ) และพยายามลดจำนวนของวัตถุ temp ที่คุณสามารถเขียนได้เช่น:

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(", ", "");
}

แก้ไข 2

การใช้คอลเล็กชันนั้นสั้นกว่า:

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

แต่ฉันก็ยังชอบเวอร์ชั่นแรกอยู่


6
-1: ฉลาดเกินไปครึ่ง หากเป้าหมายของคุณคือการทำให้โค้ดอ่านง่ายหรือมีประสิทธิภาพโซลูชัน "เหล่านี้ไม่ใช่ความคิดที่ดี 'ซ้ำ' สามารถเขียนใหม่โดยใช้ StringBuilder (การตั้งค่าความจุเริ่มต้น) และ 'repeat2' / 'repeat3' นั้นไม่มีประสิทธิภาพจริงๆและขึ้นอยู่กับไวยากรณ์ที่ไม่ระบุของสตริงที่สร้างโดย String []. toString ()
สตีเฟ่น C

@Thorb: แน่นอนด้วยรหัสนี้คุณไม่สามารถใช้ "metacharacter", [],
dfa

@ สตีเฟ่น: คำถามถูกแก้ไขเพื่อขอลูปอย่างชัดเจน คำตอบที่ใช้ StringBuilder ได้จัดเตรียมไว้แล้วดังนั้นฉันจึงหลีกเลี่ยงการโพสต์คำซ้ำ
dfa

@Stephan: ฉันไม่สามารถค้นหา downvote คำตอบที่แก้ไขของฉันไม่มีการวนซ้ำตามที่ร้องขอ ไม่มีการร้องขอเกี่ยวกับประสิทธิภาพ ฉันคิดว่าคำถามนี้เป็นเพียงความพยายามทางปัญญาในการสร้างการต่อกันโดยไม่วนซ้ำ
dfa

@Stephan: สตริงที่ผลิตผ่าน Collection.toString (และ Arrays.toString) มีการระบุไว้อย่างชัดเจนใน AbstractCollection.toString: "การแสดงสตริงประกอบด้วยรายการองค์ประกอบของคอลเลกชันตามลำดับที่ส่งคืนโดยตัววนซ้ำซึ่งอยู่ในวงเล็บเหลี่ยม () "[]") องค์ประกอบที่อยู่ติดกันจะถูกคั่นด้วยอักขระ "," (เครื่องหมายจุลภาคและเว้นวรรค) "
dfa

6

ไม่ใช่วิธีที่สั้นที่สุด แต่(ฉันคิดว่า)วิธีที่เร็วที่สุดคือใช้ StringBuilder:

 /**
   * 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 และมีผลลัพธ์ที่ดีที่สุด


4

เพื่อประโยชน์ในการอ่านและพกพา:

public String repeat(String str, int count){
    if(count <= 0) {return "";}
    return new String(new char[count]).replace("\0", str);
}

3

หากคุณกังวลเกี่ยวกับประสิทธิภาพการทำงานให้ใช้ StringBuilder ภายในลูปและทำ. toString () เมื่อออกจากลูป Heck เขียน Util Class ของคุณเองและนำมาใช้ซ้ำ 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 gigas) โดยใช้ -Xms4937m
Daniel De León


2

วนรอบง่าย

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

2
ส่งtimesไปยังตัวสร้าง StringBuilder
Behrouz.M

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): "";
Fering

โอ้ดูเหมือนว่า niczm25 จะตอบคำถามข้างล่างนี้
Fering

@Fering เหตุผลหลักเพื่อให้วิธีนี้เป็น O (log N) เฉลี่ยมากกว่า O (N) เสมอ การเพิ่มประสิทธิภาพเล็กน้อยกว่าอีกเล็กน้อยแม้ว่าจะยังไม่ดีก็ตาม
HyperNeutrino

2

โซลูชันหนึ่งบรรทัดที่ไม่ซับซ้อน:
ต้องการ Java 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. บางคนที่อ่านรหัสของคุณจะต้องเข้าใจว่าคุณกำลังทำอะไรในวงนั้น เนื่องจาก for-loop นั้นเป็นวิธีที่ใช้สำนวนนี้มันจะง่ายกว่าถ้าคุณใช้ลูป for for loop
  3. ใช่ใครบางคนอาจเพิ่มบางสิ่งที่ฉลาด แต่โดยการหลีกเลี่ยงการวนซ้ำคุณกำลังทำสิ่งที่ฉลาดทำอะไรบางอย่างฉลาดมันเหมือนกับการยิงตัวเองที่เท้าอย่างตั้งใจเพื่อหลีกเลี่ยงการยิงตัวเองที่เท้าโดยไม่ได้ตั้งใจ
  4. ข้อผิดพลาดแบบ Off-by-One นั้นง่ายต่อการจับใจด้วยการทดสอบเพียงครั้งเดียว เนื่องจากคุณควรทดสอบโค้ดของคุณข้อผิดพลาดแบบออฟไลน์ควรแก้ไขและตรวจจับได้ง่าย และมันก็ควรค่าแก่การสังเกต: โค้ดข้างต้นไม่มีข้อผิดพลาดแบบออฟไลน์ สำหรับการวนซ้ำนั้นง่ายพอ ๆ กัน
  5. ดังนั้นอย่าใช้ตัวแปรซ้ำ นั่นไม่ใช่ความผิดของ for-loop
  6. อีกครั้งดังนั้นวิธีแก้ปัญหาใดที่คุณใช้ และอย่างที่ฉันเคยสังเกตมาก่อน นักล่าบั๊กอาจจะคาดหวังให้คุณทำเช่นนี้กับ for loop ดังนั้นพวกเขาจะหาเวลาได้ง่ายขึ้นถ้าคุณใช้ for for loop

3
-1 นี่คือสองการออกกำลังกายสำหรับคุณ: ก) repetitions = -5เรียกใช้รหัสของคุณด้วย b) ดาวน์โหลด Commons Lang และใช้งานrepeatString('a', 1000)เป็นล้านครั้งในการวนซ้ำ; ทำเช่นเดียวกันกับรหัสของคุณ เปรียบเทียบเวลา repeatString('ab', 1000)สำหรับสินเชื่อพิเศษทำเช่นเดียวกันกับ
ChssPly76

2
คุณเถียงว่าโค้ดของคุณอ่านแล้วStringUtils.repeat("ab",1000)หรือไม่? เพราะนั่นคือคำตอบของฉันที่คุณได้ลงคะแนน มันยังทำงานได้ดีขึ้นและไม่มีข้อบกพร่อง
ChssPly76

2
อ่านประโยคที่ 2 ในคำถามที่คุณพูด "ฉันพยายามหลีกเลี่ยงการวนซ้ำเพราะ" ถูกเพิ่มเข้าไปในคำถามเพื่อเป็นการตอบสนองต่อคำตอบของ Andrew Hare หลังจากคำตอบของฉัน - ไม่ว่ามันจะสำคัญเพราะถ้าตำแหน่งที่คุณรับคือ "คำตอบนั้นไม่ดีถ้าห่วงคือ ใช้ที่ใดก็ได้ "ไม่มีคำตอบสำหรับคำถาม OP แม้แต่โซลูชั่นของ dfa - สร้างสรรค์อย่างที่เป็นอยู่ - ใช้สำหรับลูปภายใน "jar hell" ถูกตอบกลับไปด้านบน; คอมมอนส์ lang ถูกใช้ในทุกแอปพลิเคชั่นที่มีขนาดเหมาะสมแล้วดังนั้นจึงไม่เพิ่มการพึ่งพาใหม่
ChssPly76

2
@ ChssPly76 ณ จุดนี้ฉันค่อนข้างแน่ใจว่านักจินตนาการจะหลอก ฉันมีช่วงเวลาที่ยากลำบากจริงๆที่จะเห็นว่าใคร ๆ สามารถอ่านสิ่งที่ฉันเขียนและคิดอย่างจริงจังว่าคำตอบที่พิมพ์ไว้ด้านบน
Ethan Heilman

1
@ ChssPly76 คำตอบของฉันไม่ได้มีลูปใด ๆ :-P
Fortran

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 ฉันคิดว่าวิธีที่ดีที่สุดในการทำเช่นนี้ก็คือการใช้รหัสที่กล่าวถึงข้างต้นหรือคำตอบใด ๆ ที่นี่ แต่คอมมอนส์ lang มีขนาดใหญ่เกินไปถ้ามันเป็นโครงการขนาดเล็ก


ฉันไม่คิดว่าจะมีอะไรอีกมากที่คุณสามารถทำได้ ... อาจจะเกิน AOT !!
alexmherrmann

0

ฉันสร้างวิธีเรียกซ้ำที่ทำในสิ่งเดียวกันกับที่คุณต้องการ .. รู้สึกอิสระที่จะใช้สิ่งนี้ ...

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

ฉันมีคำตอบเดียวกันกับที่ฉันสามารถคูณสตริงใน java เพื่อทำซ้ำลำดับ?


การจัดสรรสตริงใหม่โดยไม่จำเป็นและค่าใช้จ่ายในการเรียกซ้ำ ... ไม่ดีไม่ดีไม่ดี
Alexander - Reinstate Monica

1
สิ่งนี้จะช้า ไม่แนะนำ! ใช้StringBuilderแทน
Svetlin Nakov

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

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

คุณสามารถใช้วิธีเรียกซ้ำนี้เพื่อเป้าหมายที่คุณต้องการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.