简体   繁体   中英

for loops to recursion

Im in the middle of my data structures course at uni and im trying to understand it. I have a general idea about recursion and loops in C but im having trouble understand how a loop would be implemented in erlang. For example i have the following loop from my a program of mine in 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]
}

And i dont have any clue as to how it may be implemented in erlang. I know i have to create my own definition of a loop such as:

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

(Taken from pragmatic erlang)

And then call it as follows:

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

I think i have to use a different data structure over an array such as a list but how i access the list im unsure of.

Thanks for the replies. Just an update (14/8). I have tried to make a recursion of the code as follows:

-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) -> [].

and call it as follow:

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

But it just doesn't want to work! Erlang is really a confusing language.

Let's look at "for" loop structure.

It contains initialization block , condition block and update block . Loop has a state (which at the beginning is actually defined in initialization block). No matter which data structures you want to process, because structure of loop in general would be the same. Loop state encapsulates actual data structure.

Also, you may see that condition block and update block in general are functions of loop state .

Using this information, let's create generic loop function:

-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.

Example, lets create a list of numbers from 1 to 10 (in eralng shell), using our function:

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> 

It is not the best way to create sequence of numbers, it is only for illustration. Always you might find more elegant recursive solution vs. loop solution. For our example, next solution is more preferable:

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

In shell:

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

Or just use function from standard library lists :)

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

At this point:

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

your fun is being called with the index, but you're not actually interested in the index - you need the value that was added to the list in the previous iteration. You could pass that as the fourth argument to your for function; the first time you call it, you'd need to seed it with cos(lat) , and use the new value in every recursion step.

Just in case anybody is interested. I solved the problem as follows:

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

So to call this you would enter:

     cos_lat:cos_lat(math:cos(lat),7,math:cos(lat)).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM