[英]Worst case Analysis On a loop
所以我寫了這個循環,但是我無法分析它最糟糕的時間復雜性。 任何幫助將不勝感激。
factor是任意數字primeNumber是2和factor的原始值之間的素數列表
for (int i = 0; i < primeNumbers.size() - 1; i++) {
prime = primeNumbers.get(i);
if(prime<=factor) {
if (factor % prime == 0) {
factor = factor / prime;
divisors.add(prime);
i = 0;
}
if (factor <= 3)
break;
}
else
break;
}
最糟糕的情況:因素是素數。
所以我們永遠不會break
指令。
循環體將執行primeNumbers.size()
次。
現在我們應該評估primeNumbers.size()
。
它是低於給定數量的素數 = O(n/ln n)
。
讓我們證明,獲得if (factor % prime == 0)
語句會減少計算次數。
如果我們到達那里就意味着factor = p*m
。
所以我們得到O(p/ln(p) + m/ln(m))
= O((p*ln(m) + m/ln(p))/(ln(m)*ln(p)))
< O((p*m)/(ln(m)*ln(p)))
< O((p*m)/(ln(m) + ln(p)))
= O(p*m/ln(m*p))
= O(n/ln n)
。
因此,這樣划分我們減少計算次數。
Nikolay的回答對您提出的問題做出了最直接的回應,假設每個部門的運營都有統一的成本,那么這個回答就具體就分部運營的數量而言就性能復雜性而言。 但是有兩點意見:
1)只要素數^ 2>因子,你就可以通過停止循環來顯着提高這個測試的性能。 這樣做的原因是,如果你沒有在因子的平方根之下找到除數,你也不會在平方根之上找到一個除數。 通過此修改,您將獲得更新的性能O(sqrt(n)/ ln(sqrt(n)))= O(sqrt(n)/(sqrt(n)/ 2))= O(sqrt(n) / LN(N))。
2)在數字變得足夠大以至於“有趣”的地方(即,數字不能僅僅被放入64位整數,但可以任意大),你的方法將面臨一個有趣的問題:操作查找第n項將會增長,因為在今天的大多數現有硬件上,您可能會面臨所有素數的內存管理問題。 你可能仍然可以適應32位整數的所有質數,因此發現所有小於64位的整數因子,但除此之外,你的方法將面臨明顯的麻煩。 在任何情況下,一旦你超過64位並開始尋找任意大整數的因素,如Java BigInteger,即使你可以管理內存,性能分析將需要更新以考慮你的實際整數的大小正在考慮。 尼古拉的分析很好,假設每個部門都有統一的成本。 但是,如果您開始使用更大數量的表示,則會破壞統一成本的假設。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.