代码之家  ›  专栏  ›  技术社区  ›  Bas Bossink

列表被视为长度函数的整数

  •  3
  • Bas Bossink  · 技术社区  · 16 年前

    Karate Chop Kata

    -module(chop).
    -export([chop/2]).
    -import(lists).
    -include_lib("eunit/include/eunit.hrl").
    -ifdef(TEST).
    chop_test_() -> [
        ?_assertMatch(-1, chop(3, [])),
        ?_assertMatch(-1, chop(3, [1])),
        ?_assertMatch(0,  chop(1, [1])),
     ....several asserts deleted for brevity...
    ].
    -endif.
    
    chop(N,L) -> chop(N,L,0);
    chop(_,[]) -> -1.
    chop(_, [],_) -> -1;
    chop(N, L, M) ->
        MidIndex = length(L) div 2,
        MidPoint = lists:nth(MidIndex,L),
        {Left,Right} = lists:split(MidIndex,L),
        case MidPoint of 
        _ when MidPoint < N -> chop(N,Right,M+MidIndex);
        _ when MidPoint =:= N -> M+MidIndex;
        _ when MidPoint > N -> chop(N,Left,M)
        end.
    

    ::error:badarg
     in function erlang:length/1
      called as length(1)
     in call from chop:chop/3
    

    4 回复  |  直到 16 年前
        1
  •  3
  •   Ben Hughes    16 年前

    chop(N,L) -> chop(N,L,0);
    chop(_,[]) -> -1.
    

    除此之外,在1元素列表的情况下,第n个(0,[1])将失败。我觉得这些列表可能是单索引的。

        2
  •  0
  •   Hynek -Pichi- Vychodil Paulo Suassuna    16 年前

    lists:nth/2 不是O(1)而是O(N)操作。尝试 list_to_tuple/1

    array 模块。

        3
  •  0
  •   Community Mohan Dere    12 年前

    作用 erlang:length/1 返回列表的长度。

    你调用了length(1),而1不是列表。

    length([1])将返回1 length([1,2,3,4[)将返回4

        4
  •  -1
  •   Bas Bossink    16 年前

    结合本·休斯的言论似乎可以解决这个问题。为了完整起见,我在下面粘贴了通过二分查找实现的测试。

    chop(_,[]) -> -1;
    chop(N,L) -> 
        Array = array:from_list(L),
    chop(N,Array, 0, array:size(Array)-1).
    chop(N, L, K, K) -> 
        Element = array:get(K,L),
        if 
            Element == N -> K; 
            true -> -1
        end;
    chop(_, _, K, M) when M < K -> -1;
    chop(N, L, K, M) ->
        MidIndex = K + ((M - K) div  2),
        MidPoint = array:get(MidIndex,L),
        case MidPoint of 
            N -> MidIndex;
            _ when MidPoint < N -> chop(N,L,MidIndex+1,M);
            _ -> chop(N,L,K,MidIndex-1)
        end.
    
    推荐文章