Simple way to repeat a string

后端 未结 30 3084
清酒与你
清酒与你 2020-11-21 06:55

I\'m looking for a simple commons method or operator that allows me to repeat some string n times. I know I could write this using a for loop, but I wish to avoid f

相关标签:
30条回答
  • 2020-11-21 07:12

    a straightforward one-line solution:
    requires Java 8

    Collections.nCopies( 3, "abc" ).stream().collect( Collectors.joining() );
    
    0 讨论(0)
  • 2020-11-21 07:13

    If you only know the length of the output string (and it may be not divisible by the length of the input string), then use this method:

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

    Usage demo:

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

    Don't use with empty s and length > 0, since it's impossible to get the desired result in this case.

    0 讨论(0)
  • 2020-11-21 07:15
    public static String rep(int a,String k)
    
           {
               if(a<=0)
                    return "";
               else 
               {a--;
                   return k+rep(a,k);
           }
    

    You can use this recursive method for you desired goal.

    0 讨论(0)
  • 2020-11-21 07:18
    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);
    }
    
    0 讨论(0)
  • 2020-11-21 07:18

    Simple loop

    public static String repeat(String string, int times) {
        StringBuilder out = new StringBuilder();
        while (times-- > 0) {
            out.append(string);
        }
        return out.toString();
    }
    
    0 讨论(0)
  • 2020-11-21 07:19

    So you want to avoid loops?

    Here you have it:

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

    (of course I know this is ugly and inefficient, but it doesn't have loops :-p)

    You want it simpler and prettier? use jython:

    s * 3
    

    Edit: let's optimize it a little bit :-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: I've done a quick and dirty benchmark for the 4 main alternatives, but I don't have time to run it several times to get the means and plot the times for several inputs... So here's the code if anybody wants to try it:

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

    It takes 2 arguments, the first is the number of iterations (each function run with repeat times arg from 1..n) and the second is the string to repeat.

    So far, a quick inspection of the times running with different inputs leaves the ranking something like this (better to worse):

    1. Iterative StringBuilder append (1x).
    2. Recursive concatenation log2 invocations (~3x).
    3. Recursive concatenation linear invocations (~30x).
    4. Iterative concatenation linear (~45x).

    I wouldn't ever guessed that the recursive function was faster than the for loop :-o

    Have fun(ctional xD).

    0 讨论(0)
提交回复
热议问题