"可累计数字"在C ++中

时间:2014-03-22 16:49:24

标签: c++ math

n的除数可以使数字在1到n之间。这称为可累计数。一个例子是12. 1,2,3,4,6,12可以以不同的方式加在一起,使数字1到12.现在这个代码给了我从1到用户输入的所有可累加数字,但它也是给我一些不可累加的数字,比如14.我不知道为什么会这样。我必须在代码中哪里做出改变?

#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

vector <int> divisors;
vector<int> subsetsResult;
vector<int> subset;

bool isSummableNumber(int num)
{
    if ((num > 1) && (num % 2 != 0))
    {
        return false;
    }

    for (int i=1; i<=num; i++)
    {
        if (num%i==0)
        {
            divisors.push_back(i);

            int SIZE_OF_DIVISORS_SET = divisors.size();
            double COUNTER_LIMIT     = pow(2, SIZE_OF_DIVISORS_SET) - 1;
            int TOTAL_NUMBER_OF_BITS = 8;

            for (int counter = 1; counter <= COUNTER_LIMIT; counter++)
            {
                int currentValue = counter;

                for (int bitIndex = 0; bitIndex < TOTAL_NUMBER_OF_BITS; bitIndex++)
                {
                    if (currentValue & 000001)
                    {
                        subset.push_back(divisors[bitIndex]);
                    }

                    currentValue = currentValue >> 1;
                }

                int sum = 0;
                for (std::vector<int>::iterator it = subset.begin() ; it != subset.end(); ++it)
                    sum += *it;

                if (sum >= 1 && sum <= num)
                {
                    subsetsResult.push_back(sum);
                }

            }
            subsetsResult;

            int counter = 1;
            for (std::vector<int>::iterator it = subsetsResult.begin(); it != subsetsResult.end(); ++it)
            {
                if (counter != *it)
                {
                    return false;
                }

                counter += 1;
            }

            return true;
        }
    }

}

int main()
{
    int num;
    cout << "Enter a Positive Integer: " ;
    cin >> num;

    for (int i=1; i<=num; i++)
    {
        if (isSummableNumber(i))
            cout << i << endl;

    }
    return 0;
}

3 个答案:

答案 0 :(得分:1)

我计算从0到n的所有数字的集合,它们是你到目前为止找到的除数之和。大小为n + 1的std :: vector会很好。最初,仅设置元素0。然后,如果你找到另一个除数d(伪代码)

for (i = n; i >= d; --i)
    if (resultset contains i - d)
        add i to the result set.

最后,检查该集是否包含从0到n的所有数字。

答案 1 :(得分:0)

这不会做任何事情:subsetsResult;

另外,您是否收到有关函数中未返回值的路径的编译器警告?缺少return false;和函数的结束(如果永远不会达到返回,可能会断言)。

答案 2 :(得分:0)

现在你甚至在找到所有除数之前搜索除数组合。这不是一个好主意,它可能隐藏了你的问题。

要么等到找到所有除数,然后迭代它们产生的2 ** k个和,否则当找到每个新除数时,从已知的和和新除数产生和,并跳过位操作。例如:

sums = {0}
N=14, i=1, N%i == 0, sums += i + sums => sums = {0, 1+0}
N=14, i=2, N%i == 0, sums += i + sums => sums = {0, 1, 2+0, 2+1}
N=14, i=3, N%i == 2
...
N=14, i=7, N%i == 0, sums += i + sums => sums = {0, 1, 2, 3, 7+0, 7+1, 7+2, 7+3}

现在4&lt; N和4不是总和的成员,排除14