Erlang迭代通过列表删除一个元素

时间:2012-06-10 02:35:23

标签: list functional-programming erlang runtime

我有以下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)解决方案?

2 个答案:

答案 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]).