查找整数是偶数还是奇数

时间:2015-01-06 04:14:20

标签: erlang

我正在学习Erlang,其中一个问题是根据Joe的书籍状态

  

如果X是偶数整数,函数even(X)应该返回true   否则是假的。如果X是奇整数,则odd(X)应该返回true。

我解决这个问题的方法是

-module(math_functions).

%% API
-export([even/1, odd/1]).

even(Integer) -> (Integer >= 0) and (Integer rem 2 =:= 0).
odd(Integer) -> (Integer >= 1) and (Integer rem 2 =/= 0).

并将其作为

运行
Eshell V6.2  (abort with ^G)
1> math_functions:odd(13).
true
2> math_functions:odd(-13).
false
3> math_functions:odd(1).
true
4> math_functions:even(1).
false
5> math_functions:even(2).
true
6> math_functions:even(-2).
false
7>   

我的问题是,如果有更好的方法可以做到这一点

由于

3 个答案:

答案 0 :(得分:4)

您可以使用保护将自己限制为大于或等于零的整数,然后根据问题的注释中的建议简单地检查最低有效位。您还可以使用odd/1

来定义even/1
even(X) when X >= 0 -> (X band 1) == 0.
odd(X) when X > 0 -> not even(X).

守卫是函数头的一部分,所以如果你调用even(-1)它将无法匹配,就像你调用even(1, 2)完全相同(即参数数量错误)

答案 1 :(得分:2)

回答Daydreamer关于史蒂夫回答的评论。

当你编写一个函数时,在erlang中经常使用的是仅对“成功”情况进行编码,并让不成功的情况崩溃(我稍后会回来解释为什么它很重要)。

对任何语言都有效的另一个标准是当有人使用或阅读您的代码时避免意外。

在你的一条评论中,你说你要编写的奇数和偶数函数仅限于正整数或空整数(我不会讨论这个选择,至少奇数和偶数函数仅限于整数)。这意味着你必须先问自己一个问题:如果用一个错误的参数调用它,我的函数的行为是什么。

第一个选择:让它崩溃这个史蒂夫命题:该函数只能使用正确的参数。我总是喜欢这个解决方案。唯一的例外是如果我没有掌握输入参数,例如,如果它们直接来自文件,用户界面......那么我更喜欢第三种选择。

第二选择:返回结果这是您的选择:您返回false。从逻辑的角度来看,对于奇数和偶数函数,返回false是有效的:某些事情不是真的,它是假的:o)。我不喜欢这个解决方案有两个原因。第一个问题是,除了布尔答案之外,你不能轻易地将其推广到其他东西。第二个对我来说更重要的是,它可能会让用户感到惊讶。当函数odd(N)返回false时,认为N是偶数是合理的,而在这种情况下,奇数(-2)和偶数(-2)都将返回false。

第三选择:返回标记结果这是您经常在erlang中看到的内容:函数返回{ok,Value}或{Error,Term}。这样做你可以选择调用函数来管理错误的参数错误。 Error变量允许您具有显式错误消息,对调试和用户界面非常有用。在您的示例中,代码变为:

even(X) when is_integer(X), X >= 0 -> {ok,(X band 1) == 0};
even(X) -> {illegal_param,X}.
odd(X) when is_integer(X), X >= 0 -> {ok,(X band 1) == 1};
odd(X) -> {illegal_param,X}.

编程时,尽快检测错误很重要,在erlang中它更为重要。如果一个进程未检测到(并且最简单的检测是崩溃)并且错误并通过消息传播一些无效信息,则可能很难找到问题的根本原因,忽略发出此消息的进程(可能已死)。仅对成功案例进行编码是一种尽快发现问题的简便方法。

答案 2 :(得分:0)

Find the no if even 
%functions that manipulate functions are called higher-order %functions, and the data type that represents a function in Erlang is %called a fun. here in below example you see FUNCTIONS THAT HAVE %FUNCTIONS AS THEIR ARGUMENTS

% K is an example list
1> K=[4,5,6,8,10].  
[4,5,6,8,10]

% Use lisst:filter  to perform no/2  and filter if rem=0 
2> lists:filter(fun(J)->(J rem 2)=:=0 end, K).
[4,6,8,10]


Another way:

% Function to check even

22> Checkeven=fun(U)->(U rem 2)=:=0 end. 
#Fun<erl_eval.7.126501267>

23> Checkeven(5).
false

% Define a test list
25> K=[1,2,3,4,5].
[1,2,3,4,5]

% Use lists filter to apply Checkeven func to all elements of k

26> lists:filter(Checkeven,K). 

[2,4]


%Using List comprehension

42> K.
[1,2,3,4,5]

% For all elements of K check remainder of elem/2 is zero

43> [(S rem 2=:=0) || S<-K].
[false,true,false,true,false]