我有以下erlang代码:
lists:all(fun(Element) -> somefunction(TestCase -- [Element]) end, TestCase).
TestCase是一个数组。我试图迭代列表/数组,缺少一个元素。
问题是这个代码需要O(N ^ 2)时间最坏的情况,因为每次调用--
时TestCase数组的副本。在非函数式语言中有一个明确的O(N)解决方案。
saved = TestCase[0]
temp = 0
NewTestCase = TestCase[1:]
for a in range(length(NewTestCase)):
somefunction(NewTestCase)
temp = NewTestCase[a]
NewTestCase[a] = saved
saved = temp
......或类似的东西。
erlang中是否有O(N)解决方案?
答案 0 :(得分:1)
当然有,但它有点复杂。我假设some_function/1
确实是一个布尔函数,你想测试它是否为每个子列表返回true。
test_on_all_but_one([], _Acc) -> true;
test_on_all_but_one([E|Rest], Acc) ->
case somefunction(lists:reverse(Acc,Rest)) of
true -> test_on_all_but_one(Rest, [E|Acc]);
false -> false
end.
此实现仍为O(长度(列表)^ 2),因为lists:reverse/2
调用仍需要O(length(Acc)
)。如果您可以修改somefunction/1
来对列表进行计算,将其分为两部分,那么您可以使用somefunction(lists:reverse(Acc,Rest))
或类似内容修改之前对somefunction(Acc, Rest)
的调用,并避免重建。
修改取决于somefunction/1
的内部工作原理。如果您需要更多帮助,请提供一些代码!
答案 1 :(得分:0)
如果可以接受的话,您可以将列表拆分为2个子列表。
witerate(Fun, [Tail], Acc) ->
Fun([], Acc);
witerate(Fun, [Head | Tail], Acc) ->
Fun(Tail, Acc),
witerate(Fun, Tail, [Head | Acc]).