检查一个数字是否可以被3整除

时间:2010-08-06 06:55:40

标签: division modulo integer-division

我需要查找一个数字是否可以被3整除,而不使用%/*。给出的提示是使用atoi()函数。知道怎么做吗?

17 个答案:

答案 0 :(得分:70)

当应用“添加所有数字并查看是否除以3”时,当前答案全部集中在十进制数字上。这个技巧实际上也适用于十六进制;例如0x12可以除以3,因为0x1 + 0x2 = 0x3。并且“转换”为十六进制比转换为十进制要容易得多。

的伪代码:

int reduce(int i) {
  if (i > 0x10)
    return reduce((i >> 4) + (i & 0x0F)); // Reduces 0x102 to 0x12 to 0x3.
  else
   return i; // Done.
}
bool isDiv3(int i) {
  i = reduce(i);
  return i==0 || i==3 || i==6 || i==9 || i==0xC || i == 0xF;
}

[编辑] 受R启发,更快的版本(O log log N):

int reduce(unsigned i) {
  if (i >= 6)
    return reduce((i >> 2) + (i & 0x03));
  else
   return i; // Done.
}
bool isDiv3(unsigned  i) {
  // Do a few big shifts first before recursing.
  i = (i >> 16) + (i & 0xFFFF);
  i = (i >> 8) + (i & 0xFF);
  i = (i >> 4) + (i & 0xF);
  // Because of additive overflow, it's possible that i > 0x10 here. No big deal.
  i = reduce(i);
  return i==0 || i==3;
}

答案 1 :(得分:59)

减去3直到你

a)命中0 - 数字可以被3整除

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

- 用于修复已发现问题的已编辑版本

while n > 0:
    n -= 3
while n < 0:
    n += 3
return n == 0

答案 2 :(得分:32)

将数字拆分为数字。将数字加在一起。重复,直到只剩下一位数字。如果该数字为3,6或9,则该数字可被3整除。(并且不要忘记将0视为特殊情况)。

答案 3 :(得分:17)

虽然转换为字符串然后将十进制数字加在一起的技术很优雅,但它要么需要除法,要么在转换为字符串步骤中效率低下。有没有办法直接将这个想法应用于二进制数,而不先转换为十进制数字串?

事实证明,有:

给定二进制数,如果原始数字可以被3整除,则奇数位的总和减去偶数位的总和可以被3整除。

例如:取数字3726,它可被3整除。在二进制中,这是111010001110。所以我们取奇数,从右边开始向左移动,它们是[1,1,0,1,1,1];这些的总和 5 。偶数位为[0,1,0,0,0,1];这些的总和是 2 。 5 - 2 = 3,我们可以从中得出结论,原始数字可以被3整除。

答案 4 :(得分:6)

可被3整除的数字,iirc具有一个特征,即其数字的总和可被3整除。例如,

12 -> 1 + 2 = 3
144 -> 1 + 4 + 4 = 9

答案 5 :(得分:6)

面试问题基本上要求你提出(或者已经知道)可分性规则的简写,以3作为除数。

3的可分性规则之一如下:

  

取任意数字并将数字中的每个数字加在一起。然后取出该总和并确定它是否可被3整除(重复相同的程序)。如果最终数字可以被3整除,则原始数字可以被3整除。

示例:

16,499,205,854,376
=> 1+6+4+9+9+2+0+5+8+5+4+3+7+6 sums to 69
=> 6 + 9 = 15 => 1 + 5 = 6, which is clearly divisible by 3.

另见

答案 6 :(得分:5)

给出一个数字x。 将x转换为字符串。逐字符解析字符串。将每个已解析的字符转换为数字(使用atoi())并将所有这些数字加到新的数字y中。 重复此过程,直到最终结果数字为一位数。如果该一位数是3,6或9,则原始数字x可被3整除。

答案 7 :(得分:5)

我的Java解决方案仅适用于32位无符号 int

static boolean isDivisibleBy3(int n) {
  int x = n;
  x = (x >>> 16) + (x & 0xffff); // max 0x0001fffe
  x = (x >>> 8) + (x & 0x00ff); // max 0x02fd
  x = (x >>> 4) + (x & 0x000f); // max 0x003d (for 0x02ef)
  x = (x >>> 4) + (x & 0x000f); // max 0x0011 (for 0x002f)
  return ((011111111111 >> x) & 1) != 0;
}

它首先将数字减少到小于32的数字。最后一步通过将掩码向右移动适当的次数来检查可分性。

答案 8 :(得分:3)

你没有标记这个C,但是既然你提到了atoi,那么我将给出一个C解决方案:

int isdiv3(int x)
{
    div_t d = div(x, 3);
    return !d.rem;
}

答案 9 :(得分:3)

bool isDiv3(unsigned int n)
{
    unsigned int n_div_3 =
        n * (unsigned int) 0xaaaaaaab;
    return (n_div_3 < 0x55555556);//<=>n_div_3 <= 0x55555555

/*
because 3 * 0xaaaaaaab == 0x200000001 and
 (uint32_t) 0x200000001 == 1
*/
}

bool isDiv5(unsigned int n)
{
    unsigned int n_div_5 =
        i * (unsigned int) 0xcccccccd;
    return (n_div_5 < 0x33333334);//<=>n_div_5 <= 0x33333333

/*
because 5 * 0xcccccccd == 0x4 0000 0001 and
 (uint32_t) 0x400000001 == 1
*/
}

遵循相同的规则,为了通过'n'获得可分性测试的结果,我们可以:                 将数字乘以0x1 0000 0000 - (1 / n)* 0xFFFFFFFF                 比较(1 / n)* 0xFFFFFFFF

对应的是,对于某些值,测试将无法为您要测试的所有32位数字返回正确的结果,例如,使用7的可除性:

我们得到了0x100000000-(1 / n)* 0xFFFFFFFF = 0xDB6DB6DC 和7 * 0xDB6DB6DC = 0x6 0000 0004, 我们只测试四分之一的值,但我们当然可以通过减法来避免这种情况。

其他例子:

11 * 0xE8BA2E8C = A0000 0004,值的四分之一

17 * 0xF0F0F0F1 = 10 0000 0000 1 比较0xF0F0F0F 每个价值观!

等等,我们甚至可以通过组合它们之间的自然数来测试每个数字。

答案 10 :(得分:2)

如果添加的数字中的所有数字给出结果3,6或9,则数字可被3整除。例如,3693可被3整除为3 + 6 + 9 + 3 = 21和2 + 1 = 3 3可以被3整除。

答案 11 :(得分:2)

inline bool divisible3(uint32_t x)  //inline is not a must, because latest compilers always optimize it as inline.
{
    //1431655765 = (2^32 - 1) / 3
    //2863311531 = (2^32) - 1431655765
    return x * 2863311531u <= 1431655765u;
}

在某些编译器上,这比常规方式更快:x % 3。阅读更多here

答案 12 :(得分:1)

如果数字的所有数字总和都可以被3整除,则数字可被3整除。因此,您可以将每个数字作为输入数字的子字符串,然后将它们相加。然后,您将重复此过程,直到只有一位数的结果。

如果这是3,6或9,则该数字可以除以3.

答案 13 :(得分:0)

C#用于检查数字是否可被3整除的解决方案

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = 33;
            bool flag = false;

            while (true)
            {
                num = num - 7;
                if (num == 0)
                {
                    flag = true;
                    break;
                }
                else if (num < 0)
                {
                    break;
                }
                else
                {
                    flag = false;
                }
            }

            if (flag)
                Console.WriteLine("Divisible by 3");
            else
                Console.WriteLine("Not Divisible by 3");

            Console.ReadLine();

        }
    }
}

答案 14 :(得分:0)

如果数字的总和可以被3整除,则数字可被3整除。您可以递归使用此定义,直到您留下一个数字。如果结果为3,6或9,则原始数字可以被3整除,否则不会。

Exaple:33333 =&gt; 15(3 + 3 + 3 + 3 + 3)=&gt; 6(1 + 5)所以33333可被3整除。

请参阅Divisibility rules

答案 15 :(得分:-1)

这是您的优化解决方案,每个人都应该知道.................

来源:http://www.geeksforgeeks.org/archives/511

#include<stdio.h>


int isMultiple(int n)
{
    int o_count = 0;
    int e_count = 0;


    if(n < 0)  
           n = -n;
    if(n == 0) 
           return 1;
    if(n == 1)
           return 0;

    while(n)
    {

        if(n & 1)
           o_count++;
        n = n>>1;


        if(n & 1)
            e_count++;
        n = n>>1;
    }

     return isMultiple(abs(o_count - e_count));
}


int main()
{
    int num = 23;
    if (isMultiple(num))
        printf("multiple of 3");
    else
        printf(" not multiple of 3");

    return 0;
}

答案 16 :(得分:-1)

  • 这是我提出的假algol。

让我们遵循3的倍数的二进制进度

000 011
000 110

001 001
001 100
001 111

010 010
010 101


011 000
011 011
011 110

100 001
100 100
100 111

101 010
101 101

请注意,对于以下夫妻中的3 x = abcdef 的二进制倍数 abc =(000,011),(001,100),(010,101) cde doest更改,因此,我建议的算法

divisible(x):

    y = x&7

    z = x>>3

    if number_of_bits(z)<4

        if z=000 or 011 or 110 , return (y==000 or 011 or 110) end

        if z=001 or 100 or 111 , return (y==001 or 100 or 111) end

        if z=010 or 101 , return (y==010 or 101) end

    end

    if divisible(z) , return (y==000 or 011 or 110) end

    if divisible(z-1) , return (y==001 or 100 or 111) end

    if divisible(z-2) , return (y==010 or 101) end

end