Vous voulez donc éviter les boucles?
Ici vous l'avez:
public static String repeat(String s, int times) {
if (times <= 0) return "";
else return s + repeat(s, times-1);
}
(bien sûr, je sais que c'est moche et inefficace, mais il n'a pas de boucles :-p)
Vous le voulez plus simple et plus joli? utilisez jython:
s * 3
Edit : optimisons-le un peu :-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 : J'ai fait un benchmark rapide et sale pour les 4 principales alternatives, mais je n'ai pas le temps de l'exécuter plusieurs fois pour obtenir les moyens et tracer les temps pour plusieurs entrées ... Alors voici le code si quelqu'un veut pour l'essayer:
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();
}
}
Il prend 2 arguments, le premier est le nombre d'itérations (chaque fonction s'exécute avec des temps de répétition arg de 1..n) et le second est la chaîne à répéter.
Jusqu'à présent, une inspection rapide des temps d'exécution avec différentes entrées laisse le classement quelque chose comme ça (de mieux en pire):
- Ajout de StringBuilder itératif (1x).
- Appels récursifs de concaténation log2 (~ 3x).
- Invocations linéaires de concaténation récursive (~ 30x).
- Concaténation itérative linéaire (~ 45x).
Je n'aurais jamais deviné que la fonction récursive était plus rapide que la for
boucle: -o
Amusez-vous (ctional xD).