【问题标题】:List and List value manipulations in ErlangErlang 中的列表和列表值操作
【发布时间】:2013-09-24 22:56:49
【问题描述】:

我正在学习一些 Erlang 并从书中做练习,所以我被其中一个卡住了。如果我引用整个问题然后解释我到目前为止所做的事情会更好: “如果通过重复应用,正数是快乐的 达到以下数字 1 的程序。 1.将数字的每个数字平方 2. 计算所有平方和 例如,如果您从 19 开始:

 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 是一个快乐的数字) 你怎么知道一个号码什么时候不开心?其实每一个不开心 number 最终会达到循环 4, 16, 37, 58, 89, 145, 42, 20, 4, …因此,在该循环中查找任何数字(例如 4)就足够了,并且 得出结论,原来的数字是不开心的。 编写函数happy/1和all_happy/2,返回 一个数字是否快乐(真或假)以及所有快乐的数字 分别在 N 和 M 之间。 (提示:使用函数 digitize 和 和)。 例子:

 happy(28) → true
 happy(15) → false
 happy(5, 25) → [7, 10, 13, 19, 23]"

所以,我创建了一个 digitizer/1,它给定一个正数 N 返回该数字中的数字列表:

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:

sum(N) when  N > 0 -> N + sum(N-1);
sum(0) ->   0.

因此,到目前为止,我所做的快乐数字是这样的:

happy(N) -> happy1(digitize(N), []).
happy1([], Acc) -> (Acc);
happy1([Head|Tail], Acc1) -> happy1(Tail, [Head * Head|Acc1]).

它对列表的元素进行平方,但我无法想出如何对它们求和并递归地再次执行,直到达到 1 或 4。有什么帮助或想法吗? 对于第二部分(all_happy/2),在我不称职的意见中,我应该使用列表理解,但同样,我不太确定如何实现它。感谢您的宝贵时间。

【问题讨论】:

  • 这个练习很酷:)我不知道你是否知道Euler项目......如果没有,你会发现许多其他类似的小练习来训练erlang(或任何语言)。跨度>

标签: list recursion erlang list-comprehension tail-recursion


【解决方案1】:

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

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

对于您问题的主要观点,您可以使用模式匹配来检测您是否达到了不满意的数字或是否达到了 1。

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


这是我的解决方案:

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

输出:

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 函数和构建列表的主要子句:

happy(Num) ->
  io:format("Current loop: ~p~n", [Num]),
  Digits = [ X * X || X <- digitize(Num)],
  happy(lists:sum(Digits)).

【讨论】:

  • 感谢您的帮助。实际上我想看看你对这个问题的解决方案,因为我已经尝试了我能做的一切并且我m at the point when I just want to see and understand how its 已经完成了。所以是的,如果可以的话,请发布它。再次感谢。
  • 我编辑了我的答案。我在原始帖子中有一些不准确之处;原来我误读了这个问题。现在应该是正确的,如果有什么需要澄清的,请告诉我。
  • 非常感谢,这再清楚不过了!如果可能的话,我会给你的答案投票 N 次! :) 理解似乎非常容易,当它被编写和服务时。
【解决方案2】:

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

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

使用:

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}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-06
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 2011-12-15
    • 1970-01-01
    • 2015-02-01
    相关资源
    最近更新 更多