我正在努力把握大O的想法,为今晚到期的项目的一部分,我不知道我是否正确思考这个......
该项目包括我们为数学运算编写迭代和递归解决方案。
以下是一些方法。
public int inc(int n)
{
n = n + 1;
return n;
}
public int dec(int n)
{
n = n - 1;
return n;
}
public int add(int lhs, int rhs)
{
int sum = lhs;
while (rhs > 0) {
sum = inc(sum);
rhs = dec(rhs);
} // while
return sum;
}
public int fac(int num)
{
int ans = num;
while(num > 1)
{
ans = mul(ans, dec(num));
}
return ans;
}
public int div(int lhs, int rhs) throws ArithmeticException
{
int quot = 0;
while (lhs > 0)
{
lhs = sub(lhs,rhs);
if(lhs < rhs)
{
quot = 0;
}
else
{
quot = inc(quot);
}
}
return quot;
}
public int lshift(int lhs, int rhs)
{
return mul(lhs,pow(2,rhs));
}
这些都是O(n)吗?或者只是inc,dec和add?
对于调用其他方法的行(如mul - multiply - 在fac和lshift中),是这个常数时间还是再次n,使得O(n ^ 2)?有人可以解释一下吗?
我将如何处理递归方法?
public int mul(int lhs, int rhs)
{
if (rhs == 0 || lhs == 0) return 0;
else if(rhs == 1) return lhs;
return add(lhs, mul(lhs, dec(rhs)));
}
除非有人要求其他人,否则我只会留下一个递归示例。 if和else如果被认为是每个恒定时间,对吗?然后返回调用各种其他递归方法,以及它本身(显然),我真的不知道从哪里开始。
有人试图解释这个吗?
编辑:添加了战略
public int pow(int lhs, int rhs)
{
int ans = lhs;
for(int i = rhs; i > 1; i--)
{
ans = mul(ans,lhs);
}
return ans;
}
答案 0 :(得分:1)
Big-Oh背后的想法是它是特定算法的平均运行时间。在分析运行时时,您正在寻找关键的东西,例如:
您还需要寻找其他一些内容,例如最佳和最差情况。
现在,你的方法。
inc
和dec
都是固定时间。它们不再需要依赖于传入的参数的大小来执行。
add
的大小为rhs
,因为rhs
中的每个值都会增加一步。因此运行时将是O(n)。*
mul
,根据您的递归示例,有三种情况:两个基本案例和一个迭代案例。假设基本情况是在恒定时间内运行,但由于存在迭代情况,它会超过基本情况的运行时间。
在那个例子中,你受到传入的rhs
大小的约束,所以它会在O(n)时间内运行。
fac
绑定到传入的num
大小。它将是O(n)运行时。
div
绑定到lhs
,它将在O(n)运行时。
*:谈论一个奇怪的添加两个数字的方法......
答案 1 :(得分:0)
inc
和dec
是O(1),因为它们总是可以在恒定数量的操作中完成,并且它们不依赖于您作为参数传递的值。
add
取决于你作为参数传递的数字,所以如果我们认为这个数字是我们的“顺序”,add
就是O(n)。
简单地说:你作为参数传递的值越高,你需要做的操作就越多。 由于这种增加是线性的(粗略地说,如果你增加100,你将会增加相同数量级的操作)。
您的mul
实施也将在O(n)时间内运行,因为这是您更“昂贵”的操作add
的成本。
您需要了解的是Big-O表示法的含义:算法的运行时间与输入大小的变化之间的关系。
如果你记住这一点,那么你就可以更容易地计算出你的方法的成本。