[英]Time complexity of Math.abs in Java?
对于我正在做的作业,我需要确保我有一个算法在O(n)时间内运行,并且在某些循环中使用了Math.abs()函数,因此我想知道Math.abs()
在O(1)时间运行?
我认为可以,但是我在任何地方都找不到答案。 只是想确保我不会在不知道的情况下意外地创建O(n 2 )算法。
Math.abs实现:
public static int abs(int a) {
return (a < 0) ? -a : a;
}
这将是O(1)时间复杂度,因为操作本身是恒定时间并且输入是固定的。 无论输入什么,该操作将始终节省时间。
循环: O(n):如果循环变量递增/递减恒定量,则循环的时间复杂度被视为O(n)。 例如,以下函数的时间复杂度为O(n)。
// Here c is a positive integer constant
for (int i = 1; i <= n; i += c) {
// some O(1) expressions
}
for (int i = n; i > 0; i -= c) {
// some O(1) expressions
}
这取决于您执行abs
函数的数据类型:
IEEE754浮点
abs
表示只清除保留尾数符号位的MSB
位。 这是对单个放置好的位的无条件位操作,因此为O(1)
。 这里是C ++示例(抱歉,不是JAVA程序员)
float x; // 32bit variable to perform abs on int *p=(int*)&x; // this just makes p pointer pointing to x p[0]&=0x7FFFFFFF; // clear highest bit by AND
非2'os补码有符号整数类型
它们与前面的项目符号一样具有单独的符号位,因此来自#1的所有内容也适用于这些。
int x; // 32bit variable to perform abs on x&=0x7FFFFFFF; // clear highest bit by AND
2'os补码带符号整数类型
如果设置了MSB,则表示为abs
取反。 这意味着您需要对所有位取反。
int x; // 32bit variable to perform abs on if (int(x&0x80000000)!=0) // negative means MSB is set { x^=0xFFFFFFFF; // negate all bits x++; // increment }
这也可以减少早午餐。 无论如何,对于基本数据类型仍然是O(1)
。 但是,如果您开始使用bigint
或bigdecimal
则所有位的bigdecimal
反和增量都将变为O(n)
,其中n
是用于形成数字的“数字”数。 “数字”是指内部用来存储数字的基数。 通常是2^32
或2^64
字或10
最高幂可以适合该数字。 这就是为什么通常最好不要对大数使用2'os补码...(这会使事情变得复杂,而不仅仅是abs
操作)。
结论
在基本数据类型上,您可以放心地假设abs
为O(1)
,而且大多数HW体系结构都支持此操作作为原子指令。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.