Проверьте, делится ли число на 3

мне нужно найти, делится ли число на 3 без использования %, / или *. Намек на использование . Есть идеи, как это сделать?

17 ответов


вычесть 3, пока вы либо

a) хит 0-число делится на 3

b) получить число меньше 0-число не делится

-- отредактированная версия для исправления отмеченных проблем

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

текущие ответы все внимание на десятичные цифры, при применении "добавить все цифры и посмотреть, если это делится на 3". Этот трюк на самом деле работает и в hex; например, 0x12 можно разделить на 3, потому что 0x1 + 0x2 = 0x3. И "преобразование" в hex намного проще, чем преобразование в decimal.

псевдо-код:

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

разделить число на цифры. Сложите цифры вместе. Повторяйте, пока не останется только одна цифра. Если это цифра 3, 6, или 9, то число делится на 3. (И не забудьте обработать 0 как особый случай).


хотя метод преобразования в строку, а затем добавления десятичных цифр вместе элегантен, он либо требует деления, либо неэффективен на шаге преобразования в строку. Есть ли способ применить эту идею непосредственно к двоичному числу, без предварительного преобразования в строку десятичных цифр?

оказывается, есть:

учитывая двоичное число, сумма его нечетных битов минус сумма его четных битов делится на 3, если исходное число делится на 3.

в качестве примера: возьмем число 3726, которое делится на 3. В двоичном формате это 111010001110. Поэтому мы берем нечетные цифры, начиная справа и двигаясь влево, которые [1, 1, 0, 1, 1, 1]; сумма это 5. Даже биты [0, 1, 0, 0, 0, 1]; сумма это 2. 5 - 2 = 3, из чего можно сделать вывод, что исходное число делится на 3.


число, делимое на 3, iirc имеет характеристику, что сумма его цифр делится на 3. Например,

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

вопрос интервью по существу просит вас придумать (или уже известно) правило делимости стенографии с 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.

см. также


задано число x. Преобразуйте x в строку. Разберите строку по символам. Преобразуйте каждый анализируемый символ в число (используя atoi ()) и сложите все эти числа в новое число y. Повторяйте процесс до тех пор, пока конечное результирующее число не станет длиной в одну цифру. Если эта цифра равна 3,6 или 9, исходное число x делится на 3.


мое решение на Java работает только для 32-разрядных без подписи ints.

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. Последний шаг проверяет делимость, сдвигая маску соответствующее количество раз вправо.


вы не пометили этот C, но так как вы упомянули atoi, Я собираюсь дать решение C:

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

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 = 0х6 0000 0004, Мы проверим только одну четверть значений, но мы, безусловно, можем избежать этого с помощью подстрок.

другие примеры :

11 * 0xE8BA2E8C = A0000 0004, одна четверть значений

17 * 0xF0F0F0F1 = 10 0000 0000 1 в сравнении с 0xF0F0F0F Все ценности !

Etc., мы даже можем проверить каждое число, комбинируя натуральные числа между ними.


число делится на 3, Если все цифры числа при сложении дает результат 3, 6 или 9. Например, 3693 делится на 3 как 3+6+9+3 = 21 и 2+1=3 и 3 делится на 3.


ну число делится на 3, если сумма всех цифр числа делится на 3. таким образом, вы можете получить каждую цифру в качестве подстроки входного номера, а затем добавить их. затем вы будете повторять этот процесс до тех пор, пока не будет только один результат цифры.

Если это 3, 6 или 9 число делится на 3.


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. Подробнее здесь.


в C# решение для проверки, является ли число divisble по 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();

        }

    }
}

вот вам оптимальное решение, которое каждый должен знать.................

источник: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;
}

число делится на 3, если сумма его цифр делится на 3. Это определение можно использовать рекурсивно, пока не останется одна цифра. Если результат равен 3, 6 или 9, исходное число делится на 3, иначе это не так.

примеры: 33333 => 15 (3+3+3+3+3) => 6 (1+5) так 33333 делится на 3.

посмотреть правила делимости


  • вот псевдо-Алгол, который я придумал .

давайте следить за двоичным прогрессом кратных 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 сделать изменение, следовательно, мое предложение алгоритм:

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