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):
- Iterative StringBuilder append (1x).
- Recursive concatenation log2 invocations (~3x).
- Recursive concatenation linear invocations (~30x).
- Iterative concatenation linear (~45x).
I wouldn't ever guessed that the recursive function was faster than the for loop :-o
Have fun(ctional xD).