首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Erlang中的列表和列表值操作

Erlang中的列表和列表值操作
EN

Stack Overflow用户
提问于 2013-09-24 22:56:49
回答 2查看 1.1K关注 0票数 1

我正在学习一些二郎和做练习的书,所以我被困在其中之一。我最好引用整个问题,然后解释我迄今所做的事情:“如果重复应用1下面的程序,一个正数就会很高兴。1。将数字2的每个数字都平方。例如,如果以19开头,计算所有正方形的和:

代码语言:javascript
复制
 1 * 1 + 9 * 9 = 1 + 81 = 82
 8 * 8 + 2 * 2 = 64 + 4 = 68
 6 * 6 + 8 * 8 = 36 + 64 = 100
 1 * 1 + 0 * 0 + 0 * 0 = 1 + 0 + 0 = 1 

(即19是一个快乐的数字)你怎么知道什么时候一个数字不快乐?事实上,每一个不快乐的数字最终都会达到周期4,16,37,58,89,145,42,20,4,…。因此,只要在这个循环中寻找任何数字(例如4),并得出原来的数字是不快乐的,就足够了。编写函数高兴/1和all _true/2,分别返回一个数字是否高兴(真还是假),以及N和M之间的所有高兴数。(提示:使用数字化和求和函数)。示例:

代码语言:javascript
复制
 happy(28) → true
 happy(15) → false
 happy(5, 25) → [7, 10, 13, 19, 23]"

因此,我创建了一个数字化器/1,它给定一个正数N,返回该数字中的数字列表:

代码语言:javascript
复制
digitize(N) -> digitize1(N, []).
digitize1(N, Acc) when N > 0 -> digitize1(N div 10, [N rem 10| Acc]);
digitize1(N, Acc) when N == 0 -> Acc.

,和sum/1:

代码语言:javascript
复制
sum(N) when  N > 0 -> N + sum(N-1);
sum(0) ->   0.

因此,对于那些令人高兴的数字,我迄今所做的是:

代码语言:javascript
复制
happy(N) -> happy1(digitize(N), []).
happy1([], Acc) -> (Acc);
happy1([Head|Tail], Acc1) -> happy1(Tail, [Head * Head|Acc1]).

它使列表中的元素成正方形,但我想不出如何将它们相加,直到达到1或4为止,再递归地做一次。有什么帮助或想法吗?至于第二部分(all_happy/2),在我不称职的意见中,我应该使用列表理解,但我也不太清楚如何实现它。耽误您时间,实在对不起。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-24 23:31:14

我注意到的一件事是,您的happy1循环可以直接计算和,您不需要列出一个列表,然后添加它们:

代码语言:javascript
复制
calculate([], Total)->
  Total;
calculate([First | Rest], Total) ->
  calculate(Rest, Total + (First * First)).

对于你问题的要点,你可以使用模式匹配来检测你是否达到了一个不快乐的数字,或者你已经达到了1。

我有一个可行的实现,但我猜您想自己弄清楚细节。如果你想让我发出去,请告诉我。

这是我的解决方案:

代码语言:javascript
复制
-module(happy).

-export([happy/1]).

happy(1) ->
  happy;
happy(4) ->
  not_happy;
happy(Num) ->
  io:format("Current loop: ~p~n", [Num]),
  Digits = digitize(Num),
  happy(calculate(Digits, 0)).


digitize(N) -> digitize1(N, []).
digitize1(N, Acc) when N > 0 -> digitize1(N div 10, [N rem 10| Acc]);
digitize1(N, Acc) when N == 0 -> Acc.

calculate([], Total)->
  Total;
calculate([First | Rest], Total) ->
  calculate(Rest, Total + (First * First)).

输出:

代码语言:javascript
复制
3> happy:happy(55).
Current loop: 55
Current loop: 50
Current loop: 25
Current loop: 29
Current loop: 85
Current loop: 89
Current loop: 145
Current loop: 42
Current loop: 20
not_happy
4> happy:happy(4). 
not_happy
5> happy:happy(19).
Current loop: 19
Current loop: 82
Current loop: 68
Current loop: 100
happy
6> happy:happy(20).
Current loop: 20
not_happy
7> happy:happy(21).
Current loop: 21
Current loop: 5
Current loop: 25
Current loop: 29
Current loop: 85
Current loop: 89
Current loop: 145
Current loop: 42
Current loop: 20
not_happy

如果您对如何使用列表理解感兴趣,以下是跳过计算方法并在构建列表中使用lists:sum函数的主子句:

代码语言:javascript
复制
happy(Num) ->
  io:format("Current loop: ~p~n", [Num]),
  Digits = [ X * X || X <- digitize(Num)],
  happy(lists:sum(Digits)).
票数 2
EN

Stack Overflow用户

发布于 2014-11-12 21:05:45

另一个通过尾递归实现的解决方案:

代码语言:javascript
复制
digitize(N) -> digitize1(N, [],N).
digitize1(N, Acc,M) when N > 0 -> digitize1(N div 10, [N rem 10| Acc],M);
digitize1(N, Acc,M) when N == 0 -> sum_digits(Acc,0,M).

sum_digits([],Acc,N) when Acc == 1 -> {happy,N,Acc};
sum_digits([], Acc,N) when Acc == 4 -> {unhappy,N,Acc};
sum_digits([],Acc,N) -> {digitize,Acc}, digitize1(Acc,[],N);
sum_digits([H|T],Acc,N)-> sum_digits(T,H*H+Acc,N).

使用:

代码语言:javascript
复制
1> c('test.erl').
test.erl:15: Warning: a term is constructed, but never used
{ok,test}
2> c('test.erl').
test.erl:15: Warning: a term is constructed, but never used
{ok,test}
3> c('test.erl').
test.erl:15: Warning: a term is constructed, but never used
{ok,test}
4> test:digitize(55).
{unhappy,55,4}
5> test:digitize(19).
{happy,19,1}
6> test:digitize(5). 
{unhappy,5,4}
7> test:digitize(20).
{unhappy,20,4}
8> test:digitize(21).
{unhappy,21,4}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18993488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档