【问题标题】:Finding if Integer is Even or Odd查找整数是偶数还是奇数
【发布时间】:2015-03-03 17:26:33
【问题描述】:

我正在学习ErlangJoe 的书中指出的问题之一

如果 X 是偶数并且函数 even(X) 应该返回 true 否则为假。如果 X 是奇整数,则奇数 (X) 应返回真。

我解决这个问题的方法是

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

我的问题是是否有更好的方法来做到这一点

谢谢

【问题讨论】:

  • 为什么 -13 不是奇数而 -2 不是偶数?只是好奇。
  • 我只对正整数这样做
  • 你看过最低有效位法吗? Here 是 Erlang 示例的链接。

标签: erlang


【解决方案1】:

您可以使用守卫将自己限制为大于或等于零的整数,然后只需按照问题评论中的建议检查最低有效位。你也可以用even/1来定义odd/1

even(X) when X >= 0 -> (X band 1) == 0.
odd(X) when X > 0 -> not even(X).

守卫是函数头的一部分,因此如果您调用even(-1),它将无法以与调用even(1, 2) 完全相同的方式匹配(即参数数量错误)。

【讨论】:

  • 这更加优雅和干净。那么,当条件失败时使用守卫时,返回值是什么?一个原子? truefalse?
  • 我刚刚验证,它抛出异常,** exception error: no function clause matching math_functions:even(-3) (/Users/harith/code/IdeaProjects/others/erlang/programmingErlang/src/math_functions.erl, line 15)
【解决方案2】:

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

当你编写一个函数时,erlang 中的一个常见用法是只编写“成功”的情况,让不成功的情况崩溃(我稍后会回来解释为什么它很重要)。

另一个适用于任何语言的标准是在有人使用或阅读您的代码时避免意外。

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

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

第二选择:返回结果这是你的选择:你返回 false。从逻辑的角度来看,对于奇偶函数,返回 false 是有效的:是某事不是真的,它是假的 :o)。我不喜欢这个解决方案有两个原因。第一个是除了布尔答案之外,您不能轻易地将其概括为其他东西。第二个对我来说更重要的是它可能会让用户感到惊讶。当函数odd(N)返回false时,认为N是偶数是合理的,而在这种情况下odd(-2)和even(-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中更重要。如果一个进程没有检测(最简单的检测是崩溃)和错误并通过消息传播一些无效信息,那么可能很难找到问题的根本原因,忽略哪个进程(可能死亡)发出了这个消息。只对成功案例进行编码是一种尽快发现问题的简单方法。

【讨论】:

  • 非常感谢您的详细回答,这对我来说很有意义@Pascal
【解决方案3】:
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]

【讨论】:

  • 请对您的回答进行详细解释,以便下一位用户更好地理解您的回答。
猜你喜欢
  • 2017-12-26
  • 2010-09-14
  • 2011-11-12
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
  • 2015-05-31
  • 2015-07-22
相关资源
最近更新 更多