[英]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.