0

私は大学でデータ構造コースの途中にいて、それを理解しようとしています。C での再帰とループについての一般的な考えはありますが、ループが erlang でどのように実装されるかを理解するのに苦労しています。たとえば、c で私のプログラムから次のループがあります。

int ii;
double cos_lat[8];    
for(ii = 2, cos_lat[1] = cos(lat); ii <= 7;; ii++)
{
 cos_lat[ii] = cos_lat[1] * cos_lat[ii-1]
}

そして、それがerlangでどのように実装されるかについての手がかりはありません。次のような独自のループ定義を作成する必要があることはわかっています。

for(Max, Max, F) -> [F(Max)];
for(I, Max, F) -> [F(I)|for(I+1, Max, F)].

(実用的なアーランから取得)

そして、次のように呼び出します。

for(2,7,fun(ii) -> // this is where i get stuck.

リストなどの配列に対して別のデータ構造を使用する必要があると思いますが、リストにアクセスする方法は不明です。

返信ありがとうございます。ただの更新 (14/8)。次のようにコードの再帰を試みました。

-module(cos1).
-export([cos_lat/1]).
cos_lat(Base, Iterator, Prev) -> [Base*Prev|cos_lat(Base,Iterator+1,Base*Prev)];
cos_lat(Base, 7, Prev) -> [].

次のように呼び出します。

cos1:cost_lat(cos(lat),2,cos(lat).

しかし、それはうまくいきたくないだけです!Erlang は本当に紛らわしい言語です。

4

3 に答える 3

4

「for」ループ構造を見てみましょう。

これには、初期化ブロック条件ブロック、および更新ブロックが含まれます。ループには状態があります(最初は実際には初期化ブロックで定義されています)。 一般的なループの構造は同じであるため、処理するデータ構造に関係なく。ループ状態は実際のデータ構造をカプセル化します。

また、条件ブロック更新ブロックは一般にループ状態の関数であることがわかります。

この情報を使用して、一般的なループ関数を作成しましょう。

-module( loops ).
-export( [ for/3 ] ).

for( State, ConditionFunc, LoopFunc ) ->
        case ConditionFunc( State ) of
                true ->
                        NewState = LoopFunc( State ),
                        % next iteration
                        for( NewState, ConditionFunc, LoopFunc );
                false ->
                        % terminate and return
                        State
        end.

例として、関数を使用して 1 から 10 までの数字のリストを (eralng シェルで) 作成してみましょう。

1> c(loops). 
{ok,loops}
2> 
2> ConditionFunc = 
2> fun( { 0, List } ) -> false;
2> ( _ ) -> true 
2> end.
#Fun<erl_eval.6.82930912>
3> 
3> LoopFunc = 
3> fun( { N, List } ) -> { N - 1, [ N | List ] } end. 
#Fun<erl_eval.6.82930912>
4> 
4> { _, Result } = loops:for( { 10, [] }, ConditionFunc, LoopFunc ).
{0,[1,2,3,4,5,6,7,8,9,10]}
5> 
5> Result.
[1,2,3,4,5,6,7,8,9,10]
6> 

数字のシーケンスを作成する最良の方法ではありません。説明のためだけです。常に、よりエレガントな再帰的ソリューションとループ ソリューションを見つけることができます。この例では、次のソリューションがより望ましいです。

seq( A, B ) ->
        my_seq( A - 1, B, [] ).

my_seq( A, A, List ) ->
        List;
my_seq( A, B, List ) ->
        my_seq( A, B - 1, [ B | List ] ).

シェル内:

1> loops:seq( 1, 10 ).
[1,2,3,4,5,6,7,8,9,10]

または、標準ライブラリリストの関数を使用するだけです:)

2> lists:seq( 1, 10 ).
[1,2,3,4,5,6,7,8,9,10]
于 2012-08-10T07:43:40.437 に答える
0

興味のある方は念のため。次のように問題を解決しました。

    -module(cos_lat).
    -export([cos_lat/3]).

     cos_lat(_Base, _Iterator, _Prev) ->
     cos_lat(_Base, _Iterator, _Prev, []).

     cos_lat(_Base,0, _Prev, _Co) ->
     lists:reverse(_Co);

     cos_lat(Base, Iterator, Prev, Co) -> 
     cos_lat(Base, Iterator-1, Base*Prev, [Prev*Base|Co]).

したがって、これを呼び出すには、次のように入力します。

     cos_lat:cos_lat(math:cos(lat),7,math:cos(lat)).
于 2012-08-15T07:27:56.923 に答える
0

この時点で:

for(2,7,fun(ii) -> // this is where i get stuck.

あなたfunはインデックスで呼び出されていますが、実際にはインデックスには興味がありません.前の反復でリストに追加された値が必要です. forそれを関数の 4 番目の引数として渡すことができます。初めて呼び出すときは、 でシードしcos(lat)、すべての再帰ステップで新しい値を使用する必要があります。

于 2012-08-10T13:18:29.300 に答える