我在uni的数据结构课程中,我试图理解它。我对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真的是一种令人困惑的语言。
答案 0 :(得分: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 shell中):
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 ] ).
在shell中:
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]
答案 1 :(得分:0)
此时:
for(2,7,fun(ii) -> // this is where i get stuck.
您的fun
正在使用索引进行调用,但您实际上并不对索引感兴趣 - 您需要在上一次迭代中添加到列表中的值。您可以将其作为第四个参数传递给for
函数;第一次调用它时,您需要使用cos(lat)
对其进行播种,并在每个递归步骤中使用新值。
答案 2 :(得分: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)).