有沒有什麼辦法(例如修改參數類型)使下面的'cons'函數花費的時間不是O(n)時間。即構建列表應該花費O(n)時間,而不是O(n^2)時間。常量時間'cons'
我可以在下列條件下這樣做的:
(1)沒有動態內存分配
(2)X仍必須保持有效(即可以不用臨時變量的引用)
(3)型頭可具有其單獨編譯一個構造(未可以內聯)的如何可以工作
#include <type_traits>
template <typename HEAD, typename TAIL>
struct List
{
List(HEAD head, TAIL tail) : head(head), tail(tail) {}
typename std::remove_reference<HEAD>::type head;
typename std::remove_reference<TAIL>::type tail;
};
template <typename HEAD, typename TAIL>
List<HEAD, TAIL> cons(HEAD head, TAIL tail)
{
return List<HEAD, TAIL>(head, tail);
}
struct Empty {};
int main()
{
auto x = cons(1, cons(2, cons(3, Empty())));
// x should still be valid here
}
實施例。
編譯器知道x的類型,所以在堆棧上分配空間。
使堆棧看起來是這樣的:
| Int1 | Int2 | Int3 |
| p | p+4 | p+8 |
凡p
是一個任意地址。
編譯器創建調用cons(2, cons(3, Empty()))
,將返回值指向p+4
。
Inside cons(2, cons(3, Empty()))
,編譯器創建調用cons(3, Empty())
指示返回值爲p+8
。
這樣,每次調用cons
時,不需要複製tail
。
我只是不確定代碼,所以編譯器可以(如在,被允許)做這種優化。如果有另一種獲得不斷運行時間的方式,我很樂意使用它。
我不明白你的「沒有動態內存分配」的要求。這不正是通常情況下的'缺點'嗎? –
你能解釋一下,你現在的「cons」是線性的嗎?有一定數量的爭論沒有以任何方式進行檢查。你的意思是最後的表達? –
所以你正在製作一個鏈表。它包含的不是對事物的引用,而是對它們的複製。所以我猜O(n^2)來自這樣一個事實:每個嵌套的'cons'調用都會拷貝它的參數,它將每個先前創建的對象複製到新的對象中。 –