注意,以上兩種方法都假設輸入數據已經排好序。如若不然,就要先對輸入數據進行一次排序。
最後,如果使用 Linq 的話, 還可以更簡單:
IEnumerable<Tuple<int, int, double>> Linq(IEnumerable<Tuple<int, double>> tuples)
{
var result = new List<Tuple<int, int, double>>();
var q = from k in tuples group k by k.Item1;
foreach (var g in q) result.Add(new Tuple<int, int, double> (g.Key, g.Count(), g.Average(v => v.Item2)));
return result;
}
要注意 Linq 方法無論是運行時 間還是占用的內存都更大。
我們來看看 Main 方法:
static void Main(string[] args)
{
try
{
new Program().Run(Console.Out, int.Parse(args[0]));
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
void Run(TextWriter writer, int n)
{
var tuples = GetTuples(n * 1024 * 1024);
Write("ForEach", writer, ForEach(tuples));
Write ("Iterate", writer, Iterate(tuples));
Write(" Linq ", writer, Linq(tuples));
}
其中的 Write 方法如下所示:
void Write(string title, TextWriter writer, IEnumerable<Tuple<int, int, double>> tuples)
{
writer.WriteLine("==========> " + title + " <============");
writer.WriteLine("Key ------Count Average----------");
var count = 0;
var sum = 0.0;
foreach (var t in tuples)
{
writer.WriteLine(" {0,3} {1,11:N0} {2}", t.Item1, t.Item2, t.Item3);
count += t.Item2;
sum += t.Item2 * t.Item3;
}
writer.WriteLine("--- ----------- -----------------");
writer.WriteLine(" {0,3} {1,11:N0} {2}", tuples.Count(), count, sum / count);
writer.WriteLine();
}