2012-08-22 23 views
2

例如執行數陣列上的算術,我願做類似Java中的以下內容:不反覆

int[] numbers = {1,2,3,4,5}; 
int[] result = numbers*2; 
//result now equals {2,4,6,8,10}; 

這是可以不通過數組迭代嗎?我需要使用不同的數據類型,比如ArrayList嗎?目前的迭代步驟需要一些時間,我希望這樣的事情會有所幫助。

+4

簡答:不,你不能。如果可以的話,將使用'*'運算符爲您運行迭代。 – assylias

+3

任何方法如何比O(n)更快?你必須乘以每個條目...... – Baz

+0

Haskell中可能有這樣的東西,他們喜歡「懶惰的評估」,但不是像Java這樣的語言。 – kurtzbot

回答

4

不,你不能在數組中迭代每一項而不遍歷整個數組。正如評論中指出的那樣,即使您可以使用*運算符這樣的方式,實現仍然需要觸摸數組中的每個項目。

此外,不同的數據類型將不得不做同樣的事情。

+2

只是補充一點,這個問題不受Java限制。任何其他語言都會有相同的行爲來完成OP所要求的。 –

+0

@LuiggiMendoza實際上,不,有一些函數式語言具有延遲評估,其中乘法列表上的每個元素都不會被創建,除非其他表達式實際需要它。 – Alnitak

+3

@Alnitak即使有懶惰的評估,如果你必須在操作之後迭代數組,那麼每個元素都會延遲地相乘,它不會逃避O(n)時間。 –

2

我認爲從明顯不同的答案可能有利於其他誰有同樣的問題,並不介意一層複雜性(或兩個)。

在Haskell中,有一種被稱爲「懶惰評估」的東西,你可以做一些事情,比如將一個無限大的數組乘以2,Haskell會「這樣做」。當你訪問數組時,它會根據需要嘗試評估所有內容。在Java中,我們沒有這樣的奢侈品,但我們可以以可控的方式模仿這種行爲。

您需要創建或擴展自己的List類並添加一些新功能。你需要爲每個你想要支持的數學運算提供函數。我有下面的例子。

LazyList ll = new LazyList(); 
// Add a couple million objects 
ll.multiplyList(2); 

內部實現的,這將是創建一個存儲所有需要執行的基本操作隊列,這樣操作的順序被保留。現在,每次讀取元素時,都會在返回結果之前在隊列中執行所有操作。這意味着讀取速度非常慢(取決於執行的操作數量),但我們至少可以獲得理想的結果。

如果您發現自己每次遍歷整個數組,則可能會在最後解除隊列而非保留原始值。

如果您發現您正在進行隨機訪問,我會保留原始值並在調用時返回修改後的結果。

如果您需要更新條目,您需要決定這意味着什麼。您是在那裏更換一個值,還是在操作執行後更換一個值?根據您的答案,您可能需要在隊列中反向運行以獲取「預操作」值來替換舊值。原因是,在下一次讀取同一對象時,將再次應用這些操作,然後將該值恢復到您打算在列表中替換的值。

此解決方案可能存在其他細微差別,您實施它的方式會根據您的需求以及您如何訪問(依序或隨機)完全不同,但它應該是一個好的開始。

+0

是的,這對我的應用程序來說有點過分,但絕對可以應用於更復雜的情況。 –

0

不,它不是。如果你的集合真的很大,並且你想更快地完成它,你可以嘗試在兩個或更多的線程中操作元素,但是你必須關心同步(使用synchronized集合)或者將你的集合分爲兩個(或更多)集合並在每個線程上運行一個集合。我不確定它是否會比遍歷數組更快 - 這取決於你的集合的大小以及你想要對每個元素做什麼。如果你想使用這個解決方案,你會有更快的速度 - 它可能會更慢,肯定會更復雜。 一般 - 如果它不是代碼的關鍵部分,並且執行時間不會太長,我會把它保留下來。