友好数字:运行时间太长.是什么导致的呢?算法的复杂性

Amicable Numbers: Runtime is to long. What could cause that? algorithm complexity?

本文关键字:复杂性 算法 是什么 数字 运行时间      更新时间:2023-10-16

我的代码有一点运行时问题。代码运行得很好,只是在Windows上需要几十分钟,在Linux上需要几个小时。

class AmicableNumbersBeta
{
private:
    long start;
    long end;
    std::vector<long> numbers;
protected:
    long getStart() { return start;}
    long getEnd() { return end;}
    void setStart(long start) {  this->start = start;}
    void setEnd(long end) {  this->end=end;}
    long SumOfDivisors(long value)
    {
        long result = 0;
        long half_value = value / 2;
        for (long i = 1; i <= half_value; i++)
        {
           if (value % i == 0)
           {
             result += i;
           }
        }
        return result;
    }
    void AddNumber(long value)
    {
        this->numbers.push_back(value);
    }
public:
    AmicableNumbersBeta(long Start, long End) : start(Start),end(End){}

       void Calculate()
       {
       // clear old calculation, if any
       this->numbers.clear();

       for (long i = getStart(); i < getEnd(); i++)
       {
           long s1 = SumOfDivisors(i);
           long s2 = SumOfDivisors(s1);
           if (s2 == i && i < s1)
           {
            std::cout<<"-- adding ( "<<i<<" )n";
            this->AddNumber(i);
           }
       }
    }
};

如果我现在试着运行这个程序,它开始计算Alpha直到1000000个数字被检查,它需要几个小时。但是,根据我的老师,它应该只需要几秒钟的计算。

int main() {
std::cout << "Hello, World!" << std::endl;
AmicableNumbersBeta Alpha(1,1000000);
AmicableNumbersBeta Beta( 1,100000);
AmicableNumbersBeta Gamma(1,10000);
AmicableNumbersBeta Delta(1,1000);
std::cout<<"Deltan";
Delta.Calculate();
std::cout<<"nGamman";
Gamma.Calculate();
std::cout<<"nBetan";
Beta.Calculate();
std::cout<<"nAlphan";
Alpha.Calculate();
std::cout << "Bye, World!" << std::endl;
return 0;
}

老实说,我不明白是什么原因导致了这么大的"延迟"。

我使用的平台是Linux Debian与GCC 4.9和Windows VS 15

如果有人能指出这种行为的原因,我将非常感激。

正如在注释中提到的,您的代码可以通过多种方式进行优化,通过使用记忆、筛选甚至并行。

虽然在实际的应用程序中,我可能会选择这样的优化,但您在这里不需要这样"复杂"的东西——您只需要一个改进就可以使您的代码在几秒钟内而不是几分钟内运行:您只需要计算除数到您的值的平方根。所以基本上:

long SumOfDivisors(long value)
{
    long result = 1; 
    for (long i = 2; i * i <= value; i++)
    {
       if (value % i == 0)
       {
           result += i;
           if (value / i != i) {
               result += value / i;
           }
       }
    }
    return result;
}

通过这个简单的修改,您可以在几秒钟内计算出高达1000000的友好数字。