だからあなたはループを避けたいですか?
ここにあります:
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);
}
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つ目は反復の数(各関数は1..nからのargの繰り返しで実行されます)で、2つ目は繰り返す文字列です。
これまでのところ、さまざまな入力で実行されている時間をすばやく検査すると、ランキングは次のようになります(良い方から悪い方へ)。
- 反復的なStringBuilder追加(1x)。
- 再帰的連結log2呼び出し(〜3x)。
- 再帰的連結線形呼び出し(〜30x)。
- 反復連結線形(〜45x)。
再帰関数がfor
ループよりも速いとは思いもしませんでした:-o
楽しんでください(ctional xD)。