これは、ランタイム分析による反復と再帰を使用した私の見解です。
public static class IntegerToString
{
static char[] d = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
public static string Iteration(int num, int radix = 10)
{
if (num == 0) return "0";
if (num < 0) return "-" + Iteration(Math.Abs(num));
var r = new List<char>();
while (num > 0)
{
r.Insert(0, d[num % radix]);
num /= radix;
}
return new string(r.ToArray());
}
public static string Recursion(int num, int radix = 10)
{
if (num == 0) return "0";
if (num < 0) return "-" + Recursion(Math.Abs(num));
return (num > radix - 1 ? Recursion(num / radix) : "") + d[num % radix];
}
}
キーポイント
- 基数 2 から 36 までを処理します (注意:例外処理がないため、基数が正しいことを確認する必要があります。
- 再帰メソッドの長さはわずか 3 行です。(コードゴルフスタイル)
分析
ToString()
以下は、私のコンピューター の標準と比較した両方の方法のランタイム分析です。
50 runs of 100000 items per set
Running Time:
Iteration: 00:00:02.3459591 (00:00:00.0469191 avg)
Recursion: 00:00:02.1359731 (00:00:00.0427194 avg)
Standard : 00:00:00.4271253 (00:00:00.0085425 avg)
Ratios:
| Iter | Rec | Std
-----+------+------+-----
Iter | 1.00 | 0.91 | 0.18
Rec | 1.10 | 1.00 | 0.20
Std | 5.49 | 5.00 | 1.00
結果は、反復法と再帰法が標準的な方法よりも 5.49 倍および 5.00 倍遅く実行されることを示していますToString()
。
そして、ここに私が分析に使用したコードがあります:
class Program
{
static void Main(string[] args)
{
var r = new Random();
var sw = new System.Diagnostics.Stopwatch();
var loop = new List<long>();
var recr = new List<long>();
var std = new List<long>();
var setSize = 100000;
var runs = 50;
Console.WriteLine("{0} runs of {1} items per set", runs, setSize);
for (int j = 0; j < runs; j++)
{
// create number set
var numbers = Enumerable.Range(1, setSize)
.Select(s => r.Next(int.MinValue,
int.MaxValue))
.ToArray();
// loop
sw.Start();
for (int i = 0; i < setSize; i++)
IntegerToString.Iteration(numbers[i]);
sw.Stop();
loop.Add(sw.ElapsedTicks);
// recursion
sw.Reset();
sw.Start();
for (int i = 0; i < setSize; i++)
IntegerToString.Recursion(numbers[i]);
sw.Stop();
recr.Add(sw.ElapsedTicks);
// standard
sw.Reset();
sw.Start();
for (int i = 0; i < setSize; i++)
numbers[i].ToString();
sw.Stop();
std.Add(sw.ElapsedTicks);
}
Console.WriteLine();
Console.WriteLine("Running Time:");
Console.WriteLine("Iteration: {0} ({1} avg)",
TimeSpan.FromTicks(loop.Sum()),
TimeSpan.FromTicks((int)loop.Average()));
Console.WriteLine("Recursion: {0} ({1} avg)",
TimeSpan.FromTicks(recr.Sum()),
TimeSpan.FromTicks((int)recr.Average()));
Console.WriteLine("Standard : {0} ({1} avg)",
TimeSpan.FromTicks(std.Sum()),
TimeSpan.FromTicks((int)std.Average()));
double lSum = loop.Sum();
double rSum = recr.Sum();
double sSum = std.Sum();
Console.WriteLine();
Console.WriteLine("Ratios: \n" +
" | Iter | Rec | Std \n" +
"-----+------+------+-----");
foreach (var div in new[] { new {n = "Iter", t = lSum},
new {n = "Rec ", t = rSum},
new {n = "Std ", t = sSum}})
Console.WriteLine("{0} | {1:0.00} | {2:0.00} | {3:0.00}",
div.n, lSum / div.t, rSum / div.t, sSum / div.t);
Console.ReadLine();
}