我正在努力优化速度,计算ProjectEuler - Problem 12的三角形数字。
我需要能够以某种方式初始化数组中的第一个元素:
private static ulong[] numbersArray = new ulong[5000];
计算三角形数字的一种方法是:
public static ulong GetTriangleFormula(ulong n)
{
return n * (n + 1) / 2;
}
但是它的计算复杂度介于O(n)和O(n ^ 2)之间,所以我认为我可以通过递归计算数字并将结果存储在Dictionary /数组中来交换内存的运行速度。由于三角形数字将在最终解决方案中连续计算,因此应该有效。
计算第n个三角形数字应该成为数字的简单总和[a - 2]和n。
使用字典,对于从1到1000的连续三角形数字计算,计算速度要慢得多:
private static Dictionary<ulong, ulong> numbers = new Dictionary<ulong, ulong>() { { 1, 1 } };
public static ulong GetTriangleDictionaryRecursive(ulong n)
{
if (!numbers.ContainsKey(n))
numbers[n] = n + GetTriangleDictionaryRecursive(n - 1);
return numbers[n];
}
我在字典中添加了{1,1},因此我不必总是在基本情况的GetTriangleDictionaryRecursive方法的开头检查:
if(n == 1) return 1;
但结果是它比公式方法慢了约40倍。
所以现在我正在尝试使用ulong []类型的数组编写一个方法,但我不知道如何只初始化值为1的第一个元素(其他元素是ulong 0的默认值)。
public static ulong GetTriangleArrayRecursive(ulong n)
{
if (numbersArray[n - 1] == 0)
numbersArray[n - 1] = n + GetTriangleArrayRecursive(n - 1);
return numbersArray[n - 1];
}
感谢您的帮助! :)
答案 0 :(得分:1)
我不知道它是否适合Euler问题,但总的来说,如果我想做一些比单个简单表达式更多的工作来进行初始化,我会这样做:
private static readonly ulong[] numbersArray = CreateNumbersArray();
private static ulong[] CreateNumbersArray()
{
ulong[] ret = new ulong[5000];
ret[0] = 1;
return ret;
}
或者您可以在静态构造函数中执行此操作:
private static readonly ulong[] numbersArray;
static FooClass()
{
numbersArray = new ulong[5000];
numbersArray[0] = 1;
}
顺便说一句,你真的确定把它变成一个静态变量是合适的吗?