web-dev-qa-db-ja.com

数値が3で割り切れるかどうかを確認する

_%_、_/_または_*_を使用せずに、数値が3で割り切れるかどうかを調べる必要があります。与えられたヒントは、atoi()関数を使用することでした。それを行う方法はありますか?

37
josh

どちらかになるまで3を引く

a)ヒット0-数は3で割り切れる

b)0未満の数値を取得する-数値は割り切れなかった

-指摘された問題を修正するために編集されたバージョン

while n > 0:
    n -= 3
while n < 0:
    n += 3
return n == 0
59
Forrest Voight

「すべての桁を追加し、それが3で除算されるかどうかを確認する」を適用すると、現在のところ、10進数字にすべての焦点が当てられます。そのトリックは実際には16進数でも機能します。例えば0x1 + 0x2 = 0x3であるため、0x12は3で除算できます。また、16進数への「変換」は、10進数への変換よりもはるかに簡単です。

疑似コード:

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ログログ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;
}
70
MSalters

数値を数字に分割します。数字を一緒に追加します。数字が1つだけになるまで繰り返します。その数字が3、6、または9の場合、数値は3で割り切れます(そして、特別な場合として0を処理することを忘れないでください)。

32
tdammers

文字列に変換してから10進数を一緒に追加する手法は洗練されていますが、除算が必要になるか、文字列への変換手順では非効率的です。最初に10進数の文字列に変換せずに、アイデアを2進数に直接適用する方法はありますか?

結局、あります:

2進数の場合、奇数ビットの合計から偶数ビットの合計を引いた数は、元の数が3で割り切れる場合を除いて、3で割り切れる。

例として、3で割り切れる数値3726を取り上げます。バイナリでは、これは111010001110。したがって、奇数の桁を、右から左に向かって[1、1、0、1、1、1]とします。これらの合計は5です。偶数ビットは[0、1、0、0、0、1]です。これらの合計は2です。 5-2 =3。これから、元の数は3で割り切れると結論付けることができます。

17
Tom Crockett

インタビューの質問では、本質的に、3を除数とする分割可能性ルールの省略形を考え出す(またはすでに知っている)ように求められます。

3の分割可能ルールの1つは次のとおりです。

任意の数を取り、数の各桁を加算します。次に、その合計を取り、それが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

3で割り切れる数iircには、その桁の合計が3で割り切れるという特性があります。たとえば、

12 -> 1 + 2 = 3
144 -> 1 + 4 + 4 = 9
6
Eugene Yokota

Javaの私の解決策は32ビットでのみ機能しますnsignedints。

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未満の数に減らします。最後の手順では、マスクを適切な回数だけ右にシフトすることにより、可分性をチェックします。

5
Roland Illig

与えられた数x。 xを文字列に変換します。文字列を文字ごとに解析します。解析された各文字を(atoi()を使用して)数値に変換し、これらすべての数値を新しい数値yに加算します。最終的に得られる数値が1桁になるまで、このプロセスを繰り返します。その1桁が3、6、または9の場合、元の数xは3で割り切れます。

5
Amichai

あなたはこの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 = 0x6 0000 0004を取得しました。値の4分の1のみをテストしますが、減算を使用すれば確実に回避できます。

その他の例:

11 * 0xE8BA2E8C = A0000 0004、値の4分の1

17 * 0xF0F0F0F1 = 10 0000 0000 1 0xF0F0F0Fと比較1すべての値!

等、それらの間の自然数を組み合わせることにより、すべての数をテストすることもできます。

3

追加した数値のすべての桁が3、6、または9となる場合、数値は3で割り切れます。たとえば、3693は3で割り切れます。3+ 6 + 9 + 3 = 21および2 + 1 = 3および3 3で割り切れる.

2
Kangkan
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。続きを読む こちら

2
ST3

数値の桁数の合計がすべて3で割り切れる場合、数値は3で割り切れるので、各桁を入力数値の部分文字列として取得し、それらを合計することができます。その後、結果が1桁になるまでこのプロセスを繰り返します。

これが3、6、または9の場合、数は3で割り切れます。

1
GorillaPatch

数字の合計が3で割り切れる場合、数値は3で割り切れる。この定義は、1桁になるまで再帰的に使用できる。結果が3、6、または9の場合、元の数は3で割り切れます。それ以外の場合は割り切れません。

例:33333 => 15(3 + 3 + 3 + 3 + 3)=> 6(1 + 5)なので、33333は3で割り切れます。

分割可能性ルール を参照

0
Kartik Kukreja

数値が3で割り切れるかどうかをチェックするC#ソリューション

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();

        }
    }
}
0
mr_eclair