检查数字的逻辑可以被3整除吗?

时间:2011-05-10 07:49:02

标签: c math

不使用%,/或*,我必须找到否。可以被3整除吗?

这可能是一个面试问题。

感谢。

10 个答案:

答案 0 :(得分:11)

有各种方法。最简单的很明显:

int isdivby3(int n) {
    if (n < 0) n = -n;

    while (n > 0) n -= 3;

    return n == 0;
}

但我们可以改善这一点。任何数字都可以这样表示:(“,”表示包含范围):

Base2 (AKA binary)
(0,1) + 2*(0,1) + 4*(0,1)

Base4
(0,3) + 4*(0,3) + 16*(0,3)

BaseN
(0,N-1) + N*(0,N-1) + N*N*(0,N-1)

现在的诀窍是,x数字n-1可以被x整除当且仅当n基数n-1的数字可以被1926 = 6 + 2*10 + 9*100 + 1*1000 6+2+9+1 = 8 + 1*10 8+1 = 9 thus 1926 is divisible by 9 整除时。这个技巧以9:

而闻名
number(base)

现在我们也可以在base4中将其应用于3。幸运的是,因为4是2的幂,我们可以进行二进制按位运算。我使用符号27(10) = 123(4) Digitsum 12(4) Digitsum again 3(4) = Divisible!

int div3(int n) {
    if (n < 0) n = -n;
    else if (n == 0) return 1;

    while (n > 3) {
        int d = 0;

        while (n > 0) {
            d += n & 3;
            n >>= 2;
        }

        n = d;
    }

    return n == 3;
}

现在让我们把它翻译成C:

{{1}}

快速开心。

答案 1 :(得分:10)

减去3直到你

命中0 - 数字可被3(或)

整除

得到一个小于0的数字 - 数字不可分割

 if (number > 0)
 {
        while (number > 0)
        {
            number -= 3;
    }
}
else if( number < 0)
{
    while number < 0:
        number += 3
}
return number == 0

答案 2 :(得分:6)

这是一个相当有效的大数字算法。 (考虑到约束,效果不是很高,但是合理。)

使用sprintf将其转换为字符串,将每个数字转换回数字。加上数字。如果你想出3,6或9,它可以被3整除。除了10以外的任何其他东西,它不是。超过9的任何东西,递归。

例如,为了测试数字813478902你要字符串化,然后添加数字得到42,加上这些数字得到6,所以它可以被3整除。

答案 3 :(得分:1)

只需使用for循环一次又一次减去3,看看你是否得到0.如果你得到负数而没有得到0然后你知道它不能被3整除

答案 4 :(得分:1)

打印一个可被3整除的计数序列,不带除法或模数运算符。

注意计数顺序:

00: 00(00)
01: 0001
02: 0010
03: 00(11)
04: 0100
05: 0101
06: 01(10)
07: 0111
08: 1000
09: 10(01)
10: 1010
11: 1011
12: 11(00)
13: 1101
14: 1110
15: 11(11)
16: 10000
17: 10001
18: 100(10)
19: 10011
20: 10100
21: 101(01)

请注意,那些可被3整除的数字的最后两位(括号中显示)会循环显示{00, 11, 10, 01}。我们需要检查的是计数序列的最后两位是否在序列中包含这些位。

首先我们开始与mask = 00匹配并循环,而第一个数字没有遇到低两位00。找到匹配后,我们会(mask + 03) & 0x03,它会让我们看到集合中的下一个掩码。我们继续将下一个计数的最后两位与11进行匹配。这可以通过((count & 3) == mask)

完成

代码是

#include <stdio.h>

int main (void)
{
  int i=0;
  unsigned int mask = 0x00;

  for (i=0; i<100;i++)
  {
    if ((i&0x03) == mask)
    {
      printf ("\n%d", i);
      mask = (mask + 3) & 0x03;
    }
  }
  printf ("\n");
  return 0;
}

这不是一般的。最好是使用@nightcracker建议的解决方案

另外,如果你真的想在不使用除法运算的情况下实现除法运算i。我会告诉你看看非恢复分区算法,这可以在程序中完成,对位操作符进行大量的位操作。以下是一些链接和参考资料。

Wikipedia Link

Here is a demo from UMass

另请查看Computer Organization by Carl Hamacher, Zvonko Vranesic, Safwat Zaky

答案 5 :(得分:0)

number = abs(number)

while (number > 0)
{
   number -= 3;
}

return number == 0

答案 6 :(得分:0)

假设n是有问题的数字,它是非负数。

如果n为0,则可以被3整除;否则n =(2 ^ p)*(2 * n1 + 1)并且n可被3整除iff 2 * n1 + 1,如果有k> = 0且2 * n1 + 1 = 3 *(2 * k + 1)iff n1 = 3 * k + 1 iff n1 = 1或n1> 1。 1和n1-1可被3整除。所以:

int ism3( int n)
{   for(;n;)
    {    while( !(n & 1)) n >>= 1;
         n >>= 1;
         if ( n == 0) return 0;
         n-= 1;
    }
    return 1;
 }

答案 7 :(得分:0)

知道数字是否可被3整除的最简单方法是将所有数字相加并将结果除以3.如果数字的总和可以被3整除,那么数字本身可以被3整除。例如,54467565687可被3整除,因为5 + 4 + 4 + 6 + 7 + 5 + 6 + 5 + 6 + 8 + 7 = 63,而63可以被3整除。所以,无论数字有多大,你可以找到它是否可被3整除,只是添加其所有数字,并从该和的值中减去3,直到结果小于3.如果此结果为0,则总和的值可被3整除(等等原始数字),否则总和不能被3整除(并且原始数字也不能被整除)。它比原始数字(当然,特别是如果它是一个大数字)连续减去3并且没有任何分割要快得多。嗯abraçottodos。

阿图尔

答案 8 :(得分:0)

如果数字的二进制交替数字总和为零,则数字可被3整除:

bool by3(int n) {
  int s=0;
  for (int q=1; n; s+=q*(n&1), n>>=1, q*=-1);
  return !s;
}

答案 9 :(得分:0)

您可以使用用户反馈:

int isDivisibleBy3(int n)
{
   int areDivisibleBy3[] = {};
   for(int i = 0; i < 0; i++)
   {
       if(n == areDivisibleBy3[i])
       {
           return 1;
       }
   }

   return 0;
}

当用户报告错误,指出可被3分割的数字未给出正确的结果时,您只需将该数字添加到数组中,并将数字i与for循环条件进行比较

这很棒,因为您永远不必担心用户从未使用过的数字。

不要忘记在用户报告错误时添加单元测试!