给定数字是否可以写成两个或多个连续正整数的总和?

时间:2014-10-23 00:12:57

标签: java number-theory

我需要编写一个接收int并返回true的方法,如果该数字可以写成两个或更多个连续正整数的总和,否则返回false。 / p>

boolean IsSumOfConsecutiveInts(int num)

我发现所有奇数(除了数字1)都可以写成2个连续正整数的总和:

return (num > 1 && num % 2 == 1);

但这并未考虑可以写为超过2个连续正整数(例如6 == 1 + 2 + 3)之和的数字。

如何确定一个数字是否可以写为两个或更多连续正整数的总和?

1 个答案:

答案 0 :(得分:3)

这些数字称为Polite Numbers

而且,方便的是,不是礼貌的唯一数字是2的幂。

所以,这给了我们两个选择。我们可以确定一个数字是礼貌,或者我们可以确定它不是2 的幂。

我做了两件事;后者更容易(也更有效率)。

  1. 这决定数字是否是礼貌的

    boolean IsSumOfConsecutiveInts(int num)
    {
        int sumOfFirstIIntegers = 3;
        for (int i = 2; sumOfFirstIIntegers <= num; i++)
        {
            if (i%2 == 0 ? (num%i == i/2) : (num%i == 0))
            {
                return true;
            }
            sumOfFirstIIntegers += i + 1;
        }
        return false;
    }
    

    这个很难理解。我花了一段时间才提出来。

    基本上,i是我们正在检查的连续整数的数量;

    sumOfFirstIIntegers等于第一个i整数的总和,这意味着所有可以表示为i个连续整数之和的数字大于或等于到sumOfFirstIIntegers

    值得讨论的最后一部分是布尔语句i%2 == 0 ? (num%i == i/2) : (num%i == 0)。让我们来看一些例子:

    i    all sums of i consecutive positive integers
    2    3, 5, 7, 9...
    3    6, 9, 12, 15...
    4    10, 14, 18, 22...
    5    15, 20, 25, 30...
    

    有两种情况,但在任何一种情况下,我们都可以非常简单地表达所有可能的数字,它们是i个连续整数的总和。

    1. i为偶数时,num必须等于(i * n) + (i / 2),其中n是非负整数。这当然可以写成num % i == i / 2

    2. i为奇数时,num必须等于i * n,其中n是非负整数。这给了我们第二个条件num % i == 0

    3. 除了这些条件之外,num不能小于第一个i正整数的总和。因此,我们的for循环有条件:sumOfFirstIIntegers <= num

    4. 这确定数字是否不是2 的幂:

      boolean IsSumOfConsecutiveInts(int num)
      {
          return (num & (num - 1)) != 0;
      }
      

      This answer很好地解释了为什么会有效。

    5. 请注意,上述两种解决方案都有相同的结果,它们只是思考问题的不同方式。