Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 它是一个数字';s素数部分_C++_Algorithm_Primes - Fatal编程技术网

C++ 它是一个数字';s素数部分

C++ 它是一个数字';s素数部分,c++,algorithm,primes,C++,Algorithm,Primes,我必须打印出一些方法,你可以表示一个给定的数字,因为它是素数部分 让我澄清一下:假设我得到了这个数字7。现在,首先,我必须找到所有小于7的素数,即2,3和5。现在,我可以用多少种方法来总结这些数字(我可以用一个数字,我想用多少次就用多少次),使结果等于7?例如,数字7有五种方式: 2 + 2 + 3 2 + 3 + 2 2 + 5 3 + 2 + 2 5 + 2 我完全被这项任务迷住了。首先,我想我应该创建一个可用元素数组,如:{2,2,2,3,3,5}(7/2=3,所以2必须出现三次。3也一

我必须打印出一些方法,你可以表示一个给定的数字,因为它是素数部分

让我澄清一下:假设我得到了这个数字7。现在,首先,我必须找到所有小于7的素数,即2,3和5。现在,我可以用多少种方法来总结这些数字(我可以用一个数字,我想用多少次就用多少次),使结果等于7?例如,数字7有五种方式:

2 + 2 + 3
2 + 3 + 2
2 + 5
3 + 2 + 2
5 + 2
我完全被这项任务迷住了。首先,我想我应该创建一个可用元素数组,如:{2,2,2,3,3,5}(7/2=3,所以2必须出现三次。3也一样,它会出现两次)。然后,在阵列中循环并选择一个“引线”,该引线确定我们在阵列中的距离。我知道这个解释很糟糕,下面是代码:

#include <iostream>
#include <vector>

int primes_all[25] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};

int main()
{
    int number;
    std::cin >> number;

    std::vector<int> primes_used;

    for(int i = 0; i < 25; i++) {
        if(primes_all[i] < number && number-primes_all[i] > 1) {
            for(int k = 0; k < number/primes_all[i]; k++)
                primes_used.push_back(primes_all[i]);
        }
        else break;
    }

    int result = 0;

    for(size_t i = 0; i < primes_used.size(); i++) {
        int j = primes_used.size()-1;
        int new_num = number - primes_used[i];

        while(new_num > 1 && j > -1)
        {
            if(j > -1) while(primes_used[j] > new_num && j > 0) j--;

            if(j != i && j > -1) {
                new_num -= primes_used[j];

                std::cout << primes_used[i] << " " << primes_used[j] << " " << new_num << std::endl;
            }

            j--;
        }

        if(new_num == 0) result++;
    }

    std::cout << result << std::endl;

    system("pause");
    return 0;
}
所以。。。有什么想法吗?这是一个组合问题吗?我不需要代码,只是一个想法。我仍然是C++的新手,但我会管理< /P>
请记住,3+2+2与2+3+2不同。 而且,如果给定的数字本身是素数,它将不会被计算。例如,如果给定的数字为7,则只有这些总和有效:

2 + 2 + 3
2 + 3 + 2
2 + 5
3 + 2 + 2
5 + 2
7 <= excluded
2+2+3
2 + 3 + 2
2 + 5
3 + 2 + 2
5 + 2

7动态规划是您的朋友

以数字27为例


如果7有5个结果,20有732个结果,那么您知道27至少有(732*5)个结果。您可以使用一个双变量系统(1+26、2+25…等),在运行时使用这些系统的预计算值。您不必重新计算25或26,因为您已经计算了它们。

您正在搜索的概念是数字的“素数分区”。S对一个数字的划分是一种通过增加数字来达到目标的方法;例如,1+1+2+3是7的分区。如果所有的加数都是素数,那么这个分区就是素数分区

我认为你的例子是错误的。数字7通常被认为有3个素数分区:2+2+3、2+5和7。加数的顺序无关紧要。在数论中,计算素数划分的函数是kappa,所以我们可以说kappa(7)=3

kappa的通常计算分为两部分。第一部分是计算一个数的素数因子之和的函数;例如,42=2·3·7,所以sopf(42)=12。请注意,sopf(12)=5,因为总和仅超过数字的不同因子,因此即使12=2·2·3,计算总和时也只包括一个2

给定sopf,有一个冗长的公式来计算kappa;我将以乳胶形式给出它,因为我不知道如何在这里输入:\kappa(n)=\frac{1}{n}\left(\mathrm{sopf}(n)+\sum{j=1}{n-1}\mathrm{sopf}(j)\cdot\kappa(n-j)\right)

如果您确实想要一个分区列表,而不仅仅是计数,那么@corsiKa指出了一个动态编程解决方案


我在上更详细地讨论了基本分区,包括生成计数和列表的源代码。

这里有一个高效的实现,它使用了corsiKa建议的动态编程,但没有使用他描述的算法

简单地说:如果
n
可以通过
k
不同的路径(包括单步路径,如果存在的话)到达
p
并且
p
是素数,那么我们通过将
p
附加到
n
的所有路径来构造
n+p
k路径。考虑所有这些
n
将生成一个指向
n
的有效路径的详尽列表。因此,我们只需将这样发现的路径数相加

#include <iostream>

int primes_all[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};

const int N_max = 85;
typedef long long ways;
ways ways_to_reach_N[N_max + 1] = { 1 };

int main()
{
    // find all paths
    for( int i = 0; i <= N_max; ++i ) {
        ways ways_to_reach_i = ways_to_reach_N[i];

        if (ways_to_reach_i) {
            for( int* p = primes_all; *p <= N_max - i && p < (&primes_all)[1]; ++p ) {
                ways_to_reach_N[i + *p] += ways_to_reach_i;
            }
        }
    }

    // eliminate single-step paths
    for( int* p = primes_all; *p <= N_max && p < (&primes_all)[1]; ++p ) {
        --ways_to_reach_N[*p];
    }

    // print results
    for( int i = 1; i <= N_max; ++i ) {
        ways ways_to_reach_i = ways_to_reach_N[i];

        if (ways_to_reach_i) {
            std::cout << i << " -- " << ways_to_reach_i << std::endl;
        }
    }

    return 0;
}
#包括
int primes_all[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
const int N_max=85;
路途漫长;
达到N[N_max+1]={1}的方法;
int main()
{
//找到所有路径

对于(int i=0;i)不在递归中这样做,“因为你已经这样做了”,而是在一个循环中,从为
1
构建和开始,然后为
2
等等,直到为目标数构建和为止。通过重用旧值+添加基本情况下的“单素数”来计算新值在每一步中。你不需要你的一组可以使用的数字(
primes\u used
),这超出了我的理解。你能澄清一点吗?这不会像这里建议的那样在一般情况下起作用;你忽略了primes的身份,这些都很重要,因为不同的排序很重要。你是说“至少732*5”吗结果?我是认真的吗?不,不,我没有。我应该把它写出来,因为它更正确,是的,是的,我应该写的。=)
3+2+2
被认为与
2+2+3
不同吗?是的。
3+2+2
!=
2+3+2
!=
2+2+3
这与戈德巴赫猜想有关。这是一些很酷的信息。但是,在我的情况下,
3+2
不同于
2+3
不同于
2+3
这不是正常的方式。首先,你应该向你的导师明确要求什么。然后,如果你真的想要你所说的,用谷歌搜索“重复的基本分区”或“不同的基本分区”在任何情况下,请注意,您的7的素数分区示例忽略了数字7本身,即素数,因此根据您的方法,有六种方法,而不是五种方法来创建7的分区。对不起,我想我已经提到了。我将编辑问题的描述。感谢您指出路径,tho:这是一个SPOJ问题吗?还是其他一些web编码问题te?如果是,请提供原始问题的链接。如果是作业,请发布作业的链接。这是作业,作业来自我导师的口中,从未出现在纸上,而且是芬兰语的。我尽可能地描述了问题
#include <iostream>

int primes_all[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};

const int N_max = 85;
typedef long long ways;
ways ways_to_reach_N[N_max + 1] = { 1 };

int main()
{
    // find all paths
    for( int i = 0; i <= N_max; ++i ) {
        ways ways_to_reach_i = ways_to_reach_N[i];

        if (ways_to_reach_i) {
            for( int* p = primes_all; *p <= N_max - i && p < (&primes_all)[1]; ++p ) {
                ways_to_reach_N[i + *p] += ways_to_reach_i;
            }
        }
    }

    // eliminate single-step paths
    for( int* p = primes_all; *p <= N_max && p < (&primes_all)[1]; ++p ) {
        --ways_to_reach_N[*p];
    }

    // print results
    for( int i = 1; i <= N_max; ++i ) {
        ways ways_to_reach_i = ways_to_reach_N[i];

        if (ways_to_reach_i) {
            std::cout << i << " -- " << ways_to_reach_i << std::endl;
        }
    }

    return 0;
}