0

リストを作成して印刷し、N から 1 までカウントダウンしようとしています。これが私の試みです。

%% Create a list counting down from N to 1 %%
-module(list).
-export([create_list/1]).

create_list(N) when length(N)<hd(N) ->
 lists:append([N],lists:last([N])-1),
 create_list(lists:last([N])-1); 
create_list(N) ->
 N.

これは N が 1 の場合に機能しますが、それ以外の場合は次のエラーが発生します。

172> list:create_list([2]).
** exception error: an error occurred when evaluating an arithmetic expression
     in function  list:create_list/1 (list.erl, line 6)

どんな助けでも大歓迎です。

4

3 に答える 3

4

通常、リストを作成するときは、同じものであるappendorを使用しないでください。どちらもリストの最後++に要素を追加するため、毎回リストのコピーを作成する必要があります。実用的な場合もありますが、リストの先頭で作業する方が常に高速です。

どの順序でリストを表示したいかは少し不明なので、2 つの選択肢を次に示します。

create_up(N) when N>=1 -> create_up(1, N).     %Create the list 

create_up(N, N) -> [N];
create_up(I, N) ->
    [I|create_up(I+1, N)].

create_down(N) when N>1 ->                     %Add guard test for safety
    [N|create_down(N-1)];
create_down(1) -> [1].

これらはどちらも末尾再帰ではありません。reverse末尾再帰は優れていますが、特に正しい順序でリストを取得するためにa を呼び出す必要がある場合は、必ずしも思ったほど多くの結果が得られるとは限りません。詳細については、 Erlang の神話を参照してください。

于 2012-12-14T15:56:53.940 に答える
3

私があなたの質問を正しく理解していれば、あなたが必要とするものは次のとおりです

create_list(N) when N > 0 ->
        create_list(N, []).

create_list(1, Acc) ->
        lists:reverse([1 | Acc]);
create_list(N, Acc) ->
        create_list(N - 1, [N | Acc]).

リストを扱う場合は、末尾再帰リスト構築構文を使用することをお勧めします。

また、コードを簡素化するために、ケース式の代わりに関数宣言でパターン マッチングを使用してみてください。

PS もう1つの、おそらく最も簡単な解決策は次のとおりです。

create_list(N) when N > 0 ->
        lists:reverse(lists:seq(1,N)).
于 2012-12-14T11:32:35.097 に答える
3

エラーはlists:last([N])-1です。N は入力として配列であるため、lists:last([N])N 自体を返します。あなたが期待する数ではありません。また、コードをコンパイルするときに警告が表示される場合は、別のバグがあります:lists:append要素を N 自体に追加するのではなく、戻り値に追加します。関数型プログラミングでは、変数の値を変更することはできません。

これが私の実装です:

create_list(N) ->
    create_list_iter(N, []).

create_list_iter(N, Acc) ->
    case N > 0 of
        true -> NewAcc = lists:append(Acc, [N]),
                create_list_iter(N-1, NewAcc);
        false -> Acc
    end.
于 2012-12-14T11:24:34.167 に答える