erlang 的递归不起作用。获取函数子句匹配错误
Recursion for erlang not working. Getting function clause matching error
所以我的递归遇到了问题。我收到函数子句匹配错误。当每个学生收到相同数量的糖果时,递归停止。我确定我正确地执行了递归退出条件。怎么了?
-module(assignment3).
-export([main/0, students/4, givecandy/4, teachergivecandy/4]).
main() ->
io:fwrite("Hello\n"),
students(4, 2, 2, 1). %Define how many candy each students get
givecandy(Student1, Student2, Student3, Turn) when (Student1 == Student2) and (Student2 == Student3) -> 1;
% recursivecandy(Student1, Student2, Student3, Turn) when (Student1 /= Student2) and (Student2 /= Student3) -> givecandy().
givecandy(Student1, Student2, Student3, Turn) when (Student1 /= Student2) and (Student2 /= Student3) ->
io:format("Turn123"),
Student1Total = (Student1 div 2) + (Student3 div 2),
Student2Total = (Student2 div 2) + (Student1 div 2),
Student3Total = (Student3 div 2) + (Student2 div 2),
TurnCount = Turn + 1,
teachergivecandy(Student1Total, Student2Total, Student3Total, TurnCount).
students(X, Y, Z, Turn) ->
Student1 = X,
Student2 = Y,
Student3 = Z,
TurnCount = Turn,
io:format("Turn: ~p~n" , [TurnCount]),
io:format("Student 1 Total: ~p~n" , [Student1]),
io:format("Student 2 Total: ~p~n" , [Student2]),
io:format("Student 3 Total: ~p~n" , [Student3]),
givecandy(Student1, Student2, Student3, TurnCount).
teachergivecandy(Student1Total, Student2Total, Student3Total, TurnCount) ->
io:format("hello1"),
if
Student1Total rem 2 == 1 ->
Student1FinalTotal = Student1Total + 1; %Student1FinalTotal = Student1Total + 1,
true ->
Student1FinalTotal = Student1Total
end,
if
Student2Total rem 2 == 1 ->
Student2FinalTotal = Student2Total + 1; %Student1FinalTotal = Student1Total + 1,
true ->
Student2FinalTotal = Student2Total
end,
if
Student3Total rem 2 == 1 ->
Student3FinalTotal = Student3Total + 1; %Student1FinalTotal = Student1Total + 1,
true ->
Student3FinalTotal = Student3Total
end,
io:format("Student 1 Total: ~p~n" , [Student1FinalTotal]),
io:format("Student 2 Total: ~p~n" , [Student2FinalTotal]),
io:format("Student 3 Total: ~p~n" , [Student3FinalTotal]),
io:format("Turn: ~p~n" , [TurnCount]),
givecandy(Student1FinalTotal, Student2FinalTotal, Student3FinalTotal, TurnCount).
您的 givecandy/4
没有函数子句匹配。看来你想检查所有 3 个学生是否有相同的糖果,所以你可以像下面这样更改:
givecandy(Student1, Student1, Student1, _Turn) -> 1;
givecandy(Student1, Student2, Student3, Turn) ->
io:format("Turn123"),
Student1Total = (Student1 div 2) + (Student3 div 2),
Student2Total = (Student2 div 2) + (Student1 div 2),
Student3Total = (Student3 div 2) + (Student2 div 2),
TurnCount = Turn + 1,
teachergivecandy(Student1Total, Student2Total, Student3Total, TurnCount).
shell中的结果:
1>assignment3:main().
Hello
Turn: 1
Student 1 Total: 4
Student 2 Total: 2
Student 3 Total: 2
Turn123hello1Student 1 Total: 4
Student 2 Total: 4
Student 3 Total: 2
Turn: 2
Turn123hello1Student 1 Total: 4
Student 2 Total: 4
Student 3 Total: 4
Turn: 3
1
我有下面的小代码来解决这个问题:
-module(foo).
-compile(export_all).
start()->
io:format("A B C Turns~n"),
d(4, 2, 2, 0).
d(_A, _A, _A, B) ->
io:format("~p ~p ~p ~p~n",[_A, _A, _A, B]);
d(A, B, C, D)->
io:format("~p ~p ~p ~p~n", [A, B, C, D]),
Na = check(A, B),
Nb = check(B, C),
Nc = check(C, A),
d(Na, Nb, Nc, D + 1).
even(X) when X >= 0 -> (X band 1) == 0.
check(A, B)->
N = trunc((A + B)/2),
case even(N) of
true -> N;
false -> N + 1
end.
shell中的结果:
> foo:start().
A B C Turns
4 2 2 0
4 2 4 1
4 4 4 2
ok
您有两个 givecandy
的子句,带有保护条件 (Student1 == Student2) and (Student2 == Student3)
和 (Student1 /= Student2) and (Student2 /= Student3)
。但也可能是两个守卫都失败了,例如givecandy(1,2,2)
。
可能其中一个递归调用最终看起来像那样("probably" 因为您没有在问题中包含错误消息,它应该准确说明问题所在的函数和参数)。因此,您需要添加另一个子句来处理这种情况或更改守卫。
最后一个子句没有守卫是一种很好的做法,这样它就可以处理所有缺失的情况。当然,也有可能是实在不行就抛异常吧!
所以我的递归遇到了问题。我收到函数子句匹配错误。当每个学生收到相同数量的糖果时,递归停止。我确定我正确地执行了递归退出条件。怎么了?
-module(assignment3).
-export([main/0, students/4, givecandy/4, teachergivecandy/4]).
main() ->
io:fwrite("Hello\n"),
students(4, 2, 2, 1). %Define how many candy each students get
givecandy(Student1, Student2, Student3, Turn) when (Student1 == Student2) and (Student2 == Student3) -> 1;
% recursivecandy(Student1, Student2, Student3, Turn) when (Student1 /= Student2) and (Student2 /= Student3) -> givecandy().
givecandy(Student1, Student2, Student3, Turn) when (Student1 /= Student2) and (Student2 /= Student3) ->
io:format("Turn123"),
Student1Total = (Student1 div 2) + (Student3 div 2),
Student2Total = (Student2 div 2) + (Student1 div 2),
Student3Total = (Student3 div 2) + (Student2 div 2),
TurnCount = Turn + 1,
teachergivecandy(Student1Total, Student2Total, Student3Total, TurnCount).
students(X, Y, Z, Turn) ->
Student1 = X,
Student2 = Y,
Student3 = Z,
TurnCount = Turn,
io:format("Turn: ~p~n" , [TurnCount]),
io:format("Student 1 Total: ~p~n" , [Student1]),
io:format("Student 2 Total: ~p~n" , [Student2]),
io:format("Student 3 Total: ~p~n" , [Student3]),
givecandy(Student1, Student2, Student3, TurnCount).
teachergivecandy(Student1Total, Student2Total, Student3Total, TurnCount) ->
io:format("hello1"),
if
Student1Total rem 2 == 1 ->
Student1FinalTotal = Student1Total + 1; %Student1FinalTotal = Student1Total + 1,
true ->
Student1FinalTotal = Student1Total
end,
if
Student2Total rem 2 == 1 ->
Student2FinalTotal = Student2Total + 1; %Student1FinalTotal = Student1Total + 1,
true ->
Student2FinalTotal = Student2Total
end,
if
Student3Total rem 2 == 1 ->
Student3FinalTotal = Student3Total + 1; %Student1FinalTotal = Student1Total + 1,
true ->
Student3FinalTotal = Student3Total
end,
io:format("Student 1 Total: ~p~n" , [Student1FinalTotal]),
io:format("Student 2 Total: ~p~n" , [Student2FinalTotal]),
io:format("Student 3 Total: ~p~n" , [Student3FinalTotal]),
io:format("Turn: ~p~n" , [TurnCount]),
givecandy(Student1FinalTotal, Student2FinalTotal, Student3FinalTotal, TurnCount).
您的 givecandy/4
没有函数子句匹配。看来你想检查所有 3 个学生是否有相同的糖果,所以你可以像下面这样更改:
givecandy(Student1, Student1, Student1, _Turn) -> 1;
givecandy(Student1, Student2, Student3, Turn) ->
io:format("Turn123"),
Student1Total = (Student1 div 2) + (Student3 div 2),
Student2Total = (Student2 div 2) + (Student1 div 2),
Student3Total = (Student3 div 2) + (Student2 div 2),
TurnCount = Turn + 1,
teachergivecandy(Student1Total, Student2Total, Student3Total, TurnCount).
shell中的结果:
1>assignment3:main().
Hello
Turn: 1
Student 1 Total: 4
Student 2 Total: 2
Student 3 Total: 2
Turn123hello1Student 1 Total: 4
Student 2 Total: 4
Student 3 Total: 2
Turn: 2
Turn123hello1Student 1 Total: 4
Student 2 Total: 4
Student 3 Total: 4
Turn: 3
1
我有下面的小代码来解决这个问题:
-module(foo).
-compile(export_all).
start()->
io:format("A B C Turns~n"),
d(4, 2, 2, 0).
d(_A, _A, _A, B) ->
io:format("~p ~p ~p ~p~n",[_A, _A, _A, B]);
d(A, B, C, D)->
io:format("~p ~p ~p ~p~n", [A, B, C, D]),
Na = check(A, B),
Nb = check(B, C),
Nc = check(C, A),
d(Na, Nb, Nc, D + 1).
even(X) when X >= 0 -> (X band 1) == 0.
check(A, B)->
N = trunc((A + B)/2),
case even(N) of
true -> N;
false -> N + 1
end.
shell中的结果:
> foo:start().
A B C Turns
4 2 2 0
4 2 4 1
4 4 4 2
ok
您有两个 givecandy
的子句,带有保护条件 (Student1 == Student2) and (Student2 == Student3)
和 (Student1 /= Student2) and (Student2 /= Student3)
。但也可能是两个守卫都失败了,例如givecandy(1,2,2)
。
可能其中一个递归调用最终看起来像那样("probably" 因为您没有在问题中包含错误消息,它应该准确说明问题所在的函数和参数)。因此,您需要添加另一个子句来处理这种情况或更改守卫。
最后一个子句没有守卫是一种很好的做法,这样它就可以处理所有缺失的情况。当然,也有可能是实在不行就抛异常吧!