Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.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
Python 欧拉项目#29备选方案_Python_C_Algorithm_Math_Combinatorics - Fatal编程技术网

Python 欧拉项目#29备选方案

Python 欧拉项目#29备选方案,python,c,algorithm,math,combinatorics,Python,C,Algorithm,Math,Combinatorics,这是一个关于项目Euler问题的问题。 您可以在此处找到问题的描述: 好的,首先,让我澄清一下,我已经解决了这个问题,我只是在寻找一个基于数学的替代解决方案 第二,为了不破坏尚未解决的问题,如果您尚未解决,请不要继续。:) 因此,我使用Python解决了这个问题,因为它支持大数字和列表理解,所以我能够想出一个单行线: print(len(set([a ** b for a in range(2, 101) for b in range(2, 101)]))) 现在,我试图用C语言解决这个问题,

这是一个关于项目Euler问题的问题。 您可以在此处找到问题的描述:

好的,首先,让我澄清一下,我已经解决了这个问题,我只是在寻找一个基于数学的替代解决方案
第二,为了不破坏尚未解决的问题,如果您尚未解决,请不要继续。:)

因此,我使用Python解决了这个问题,因为它支持大数字和列表理解,所以我能够想出一个单行线:

print(len(set([a ** b for a in range(2, 101) for b in range(2, 101)])))
现在,我试图用C语言解决这个问题,方法是使用更多的数学知识(C语言本身不支持大数字或列表理解)。 我遇到了这样一条线索:接受的答案给了我一些想法,我想出了以下代码:

int main(void) {

    int found[1000];    // an array where I hold the found values(0 or 1)
    int e, b, i, count, x;

    count = 0;     // number of duplicates
    x = 3;
    for(i = 0; i < 1000; i++)
         found[i] = 0;


    for(e = 1; (int)pow(x, e) <= 100; e++) {
        for(b = 2; b <= 10; b++) {
            if(found[e * b])    // if the value has been found, then we have duplicate
                count++;
            found[e * b] = 1;   // mark that we found the value
        }
    }

    printf("count: %d\n", count);

    return 0;
}
int main(无效){
int found[1000];//保存找到的值(0或1)的数组
int e,b,i,count,x;
计数=0;//重复数
x=3;
对于(i=0;i<1000;i++)
发现[i]=0;

对于(e=1;(int)pow(x,e)而言,发现重叠数的观测值如下所示
首先,让我们将范围设置为从2到10,这样数字将类似于
22、23、24、25、26、27、28、29、210
32、33、34、35、36、37、38、39、310
42、43、44、45、46、47、48、49、410
52、53、54、55、56、57、58、59、510
62、63、66、65、66、67、68、69、610
72,73,77,75,77,77,78,79,710
82,83,88,85,88,88,88,89,810
92、93、94、95、96、97、99、99、910
102、103、104、105、106、107、108、109、1010
关键点是42=(22)2=24 因此,42、43、44、45、46、47、48、49、410将是 24、26、28、210、212、214、216、218、220 您是否注意到,在210之前,我们仍然有重复的数字,之后我们开始有一个新的数字
因此,用这个观察结果重写上面的数字,
22、23、24、25、26、27、28、29、210
32、33、34、35、36、37、38、39、310
24,25,28,210212,214,216,218,220
52、53、54、55、56、57、58、59、510
62、63、64、65、66、67、68、69、610
72、73、74、75、76、77、78、79、710
26、29、212、215、218、221、224、227、230
34,36,38,310312,314,316,318,320
102、103、104、105、106、107、108、109、1010
所以我们需要跟踪我们得到它的幂的数字,例如我们从22开始,数字是2,幂是2,增加幂的间隔是1。 它的代码是:

vector<int>  calcCache(int rangeStart, int rangeEnd)
{
    int maxBase = rangeEnd*rangeEnd;
    int maxStartPow = 1;
    while (maxBase > 0)
    {
        maxBase /= 2;
        maxStartPow++;
    }
    maxStartPow /= 2;
    vector<bool> seen(maxStartPow*rangeEnd, false);
    int i = rangeStart;
    vector<int> cahce;


    int maxprev = 0;

    int gap = 1;
    int startpow = 2 * gap;
    int j = pow(i, startpow);

    int diff = rangeEnd - rangeStart;
    int maxCurrent = diff*gap + startpow;

    while (j <= rangeEnd*rangeEnd)
    {

        int currPow = startpow;
        int k = 0;
        int currRes = 0;
        while (k <= diff)
        {

            if (!seen[currPow])
            {
                currRes++;
            }
            seen[currPow] = true;
            currPow += gap;
            k++;
        }
        cahce.push_back(currRes);

        maxprev = currPow - gap;


        gap++;
        startpow = 2 * gap;
        j = pow(i, startpow);
    }

    return cahce;
}
int distinctpowers(int rangeStart, int rangeEnd)
{
    vector<bool> arr(rangeEnd*rangeEnd + 1, false);
    int res = 0;

    vector<int> cache = calcCache(rangeStart, rangeEnd);
    for (int i = rangeStart; i <= rangeEnd; i++)
    {

        if (!arr[i*i])
        {
            int maxprev = 0;

            int gap = 1;
            int startpow = 2 * gap;
            int j = pow(i, startpow);

            int diff = rangeEnd - rangeStart;
            int maxCurrent = diff*gap + startpow;

            while (j <= rangeEnd*rangeEnd)
            {

                int currPow = startpow;
                res += cache[gap - 1];

                maxprev = currPow - gap;
                arr[j] = true;

                gap++;
                startpow = 2 * gap;
                j = pow(i, startpow);


            }
        }
    }
    return res;
}
在那之后,我们需要跟踪我们所看到的力量,你能遇到的最大力量是maxStartPow*rangeEnd

vector<bool> seen(maxStartPow*rangeEnd, false);
看到的向量(maxStartPow*rangeEnd,false);
然后我们开始在我们的基础上一行一行地走,在这个例子2中,每一行都记得我们看到的力量,当我们看到新的力量时,我们增加了这一行的结果。
这段代码最重要的部分是,在计算完每一行之后,我们需要存储它,因为我们将在主要问题中重用它

int maxprev = 0;

int gap = 1;
int startpow = 2 * gap;
int j = pow(i, startpow);

int diff = rangeEnd - rangeStart;
int maxCurrent = diff*gap + startpow;

while (j <= rangeEnd*rangeEnd)
{

    int currPow = startpow;
    int k = 0;
    int currRes = 0;
    while (k <= diff)
    {

        if (!seen[currPow])
        {
            currRes++;
        }
        seen[currPow] = true;
        currPow += gap;
        k++;
    }
    cahce.push_back(currRes);

    maxprev = currPow - gap;


    gap++;
    startpow = 2 * gap;
    j = pow(i, startpow);
}
intmaxprov=0;
int gap=1;
int startpow=2*间隙;
int j=功率(i,起动功率);
int diff=范围结束-范围开始;
int maxCurrent=diff*gap+startpow;

while(如果您想改进工作代码,应该转到:)谢谢你,我会考虑的!这只是因为它产生了错误的结果,所以没有真正起作用。我使用了与你完全相同的一条线性。但是,如果你想要一个更数学的方法,你可以不用计算幂。例如,64可以写为43和82,因为26=(23)**2=(2**2)**3.也就是说,我们写6=3*2=2*3,使用指数定律。当然,这适用于任何基数,而不仅仅是2,对于任何指数,你都可以将因子分解为不同的因子。现在你必须担心重复计算。是的,如果你看到我上面提到的线索,这就是他提到的,根据他的回答,我试图解决这个问题如你所说,基本问题是重复计算每次
count
递增时,试着打印出x,e,b。然后你就可以看到你在数什么。你在这个答案上帮了我很多忙!但是,我认为有一些问题。首先,当你在代码之前从2到10做这个例子时,你把第7行的2^15重复计算,如果我没有错的话,就不会了。这就是对于rangeStart=2和rangeEnd=10,它返回68,而应该返回69(代码还将2^15计为重复)。最后,对于rangeStart=2和rangeEnd=100,这是PE问题,它返回9068,而它应该返回9183,可能是因为上述原因。尽管如此,感谢您的时间!:)是的,您是对的:)。我将更正它并添加另一个增强功能!在计算完基2的所有功率后,我们将保存结果并重新使用它以3、4、5为基数。等等。哦,老兄,你在这方面花了很多时间,非常感谢!!:)我也在尝试通过结合我们的代码思想来找到解决问题的方法!它正在工作!!:)如果你能解释一下它是如何工作的,或者发表一些评论,我将不胜感激,因为它是一个非常大的代码(虽然很快)。无论如何,非常感谢!!!
vector<bool> seen(maxStartPow*rangeEnd, false);
int maxprev = 0;

int gap = 1;
int startpow = 2 * gap;
int j = pow(i, startpow);

int diff = rangeEnd - rangeStart;
int maxCurrent = diff*gap + startpow;

while (j <= rangeEnd*rangeEnd)
{

    int currPow = startpow;
    int k = 0;
    int currRes = 0;
    while (k <= diff)
    {

        if (!seen[currPow])
        {
            currRes++;
        }
        seen[currPow] = true;
        currPow += gap;
        k++;
    }
    cahce.push_back(currRes);

    maxprev = currPow - gap;


    gap++;
    startpow = 2 * gap;
    j = pow(i, startpow);
}