2013-12-10 91 views
2

我想做一个算法,返回是否是奇数或奇数,而不使用像mod,div,odd()这样的内置函数。 只有我提出了解决方案之后,但它是不稳健,只对数字远高于0Pascal - 奇数和偶数

Var 
    n: integer; 

begin 
    ReadLn(n); 
    While (n not in [1, 0]) do 
    n:=n-2; 
    if n = 1 then 
    WriteLn('odd') 
    else 
    WriteLn('even'); 
end. 

谢谢您的帮助。

+3

为什么不只是使用'if(n和1)= 1 then'? – Michael

+1

@Michael,'和'是一个布尔运算符而不是一个按位运算符。至少不是在原来的帕斯卡。 – lhf

+0

@lhf:好的。在接近15年的时间里,我没有编码Pascal,所以我只是在互联网上查找了一个运营商表格(这显然是用于FreePascal的,但我认为它也适用于Turbo Pascal)。 – Michael

回答

2

好,使之与负数工作,你可以只检查,如果数字为负,如果是,乘与-1(或只使用abs)。

算法的唯一问题是效率;在o(n)中运行。一些其他的想法:

  • 检查至少显著位(这可能是最后一次)
  • 整数除法2(可以通过划分和TRUNC做),该 繁衍的结果与2,检查它是否相同数量的
  • 检查的最后一个数字是0,2,4,6,8(真的很不错,如果数目给定为 字符串/数组)在你的算法的每一步提高 扣除数,直到你击中负面然后扭转过程。对于 例如,让我们说,我们想要查询64:

    1. 64 - 2 = 62,这是> 0但不为0或1
    2. 63 - 4 = 58,> 0,不0/1
    3. 50 - 8 = 42,> 0,不0/1
    4. 42 -16 = 26,> 0,不0/1
    5. 26 -32 = -6,< 0 =>反向
    6. 26 - 16 = 10,> 0,而不是0/1
    7. 10 - 8 = 2,> 0,而不是0/1
    8. 2 - 4 = -2,< 0 =>反向
    9. 2 - 2 = 0,= 0 =>甚至

所以10个步骤,而不是63
注意,后第一个相反,我们减少每一步的相减数,因为我们知道它小于我们减去的数的2倍。当然,你可以创建大量的变体,其中一些可能更有效。

0

如果一个数字是奇数,它的最后一位是1,否则为0。您可以使用一个按位运算符来测试整数(1),它表示为0..00001。

我帕斯卡尔技能是有些生疏,但它应该是类似的东西:

var 
    n: integer; 
begin 
    readln(n); 
    if(n&1 = 1) then 
    writeln('odd') 
    else 
    writeln('even'); 
end. 
+0

我不认为在Pascal中有'&'运算符。当我使用它时... – lhf

+0

这应该是'如果n和1 = 1然后writeln('odd')else writeln('even');' –

+0

在J&W Pascal中没有逻辑,只是布尔型。二进制机器和二进制补码在当时并不能保证。 –

0

你可以使用cos?如果是这样,尝试

abs(cos(n*1.570796326794896619231321691639751442)) > 0.9 

它确实应该= 1但我们不能用π/ 2的完美价值,就会有一个小错误在COS ...

0

我从来没有真正使用J & W Pascal,但我知道很多位操作符都缺失。

但是我确实使用了Pascal的后继Modula2,而在M2中,一个整数转换为相同大小的集合。如果这也适用于经典的帕斯卡,那么你可以做

Type 
    TIntBitset = [0..31]; // or whatever your word size is. 

if 0 in TIntBitSet(i) then 
    begin 
    (* odd! *) 
    end;