我正试图解决一些面试问题,所以我盯着一个简单的问题。
设计阶乘函数。
这个函数是一个叶子(没有依赖 - 很容易测试),所以我在帮助器类中使它成为静态的。
public static class MathHelper
{
public static int Factorial(int n)
{
Debug.Assert(n >= 0);
if (n < 0)
{
throw new ArgumentException("n cannot be lower that 0");
}
Debug.Assert(n <= 12);
if (n > 12)
{
throw new OverflowException("Overflow occurs above 12 factorial");
}
int factorialOfN = 1;
for (int i = 1; i <= n; ++i)
{
//checked
//{
factorialOfN *= i;
//}
}
return factorialOfN;
}
}
测试:
[TestMethod]
[ExpectedException(typeof(OverflowException))]
public void Overflow()
{
int temp = FactorialHelper.MathHelper.Factorial(40);
}
[TestMethod]
public void ZeroTest()
{
int factorialOfZero = FactorialHelper.MathHelper.Factorial(0);
Assert.AreEqual(1, factorialOfZero);
}
[TestMethod]
public void FactorialOf5()
{
int factOf5 = FactorialHelper.MathHelper.Factorial(5);
Assert.AreEqual(5*4*3*2*1,factOf5);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void NegativeTest()
{
int factOfMinus5 = FactorialHelper.MathHelper.Factorial(-5);
}
我有几个问题:
谢谢
答案 0 :(得分:3)
对我来说看起来是对的,但是对于更大的数字来说效率会很低。如果你允许大整数,那么随着每个乘法的增加,这个数字会不断增长,所以如果你将它们成倍增加,你会看到一个巨大的(渐近更好的)速度增加。例如:
bigint myFactorial(uint first, uint last)
{
if (first == last) return first;
uint mid = first + (last - first)/2;
return myFactorial(first,mid) * myFactorial(1+mid,last);
}
bigint factorial(uint n)
{
return myFactorial(2,n);
}
如果你真的想要一个快速的阶乘方法,你也可以考虑这样的事情:
答案 1 :(得分:3)
如果我是你的面试官,我会问以下一些后续问题:
n==0
案例吗?作为一名采访者,我肯定会有一些这样的曲线球向你投掷。一般来说,我喜欢用白板和模拟面试者练习的方法,因为很多都是敏捷的,并且想着站起来。
答案 2 :(得分:0)
在for循环中,你可以从for(int i = 2 ...)开始。乘以1是没用的。 我会为两个&lt;抛出一个ArgumentOutOfRangeException。 0和&gt; 12.当您使用单元测试时,Debug.Assert将屏蔽异常(您必须在发布模式下测试它)。