簡體   English   中英

鑒於一個數的素因數分解,生成一個數的所有除數

[英]Generating all divisors of a number given its prime factorization

我想找到[1,10 7 ]范圍內的所有數字除數。 我知道可以在O(sqrt(n))中解決。 但是在此之前必須運行Eratosthenes篩,可以容易地對其進行修改以獲得數字的質因式分解(通過跟蹤每個數字的質因之一)。 所以我想知道使用素數分解生成所有因子會更有效嗎?
令n = p 1 k 1 * p 2 k 2 * .... * p m k m

我認為這種表示法可以在O(M +ΣKⅰ)篩后獲得。
經過一番思考,我提出了以下代碼來生成因素:

int factors[]={2,5};        // array containing all the factors
int exponents[]={2,2};      // array containing all the exponents of factors
                            // exponents[i] = exponent of factors[i]
vector <int> ans;           // vector to hold all possible factors

/*
*   stores all possible factors in vector 'ans'
*   using factors and exponents from index l to r(both inclusive)
*/
void gen(int factors[],int exponents[],vector<int>& ans,int l,int r)
{
    if(l==r)                        
    {
        int temp = 1;
        for(int i=0;i<=exponents[l];i++)
        {
            ans.push_back(temp);
            temp *= factors[l];
        }
        return;
    }
    gen(factors,exponents,ans,l+1,r);
    int temp=factors[l];
    int size = ans.size();
    for(int i=1;i<=exponents[l];i++)
    {
        for(int j=0;j<size;j++)
        {
            ans.push_back(ans[j]*temp);
        }
        temp *= factors[l];
    }
}

我認為其時間復雜度是至少Ω(無因子)=Ω(Π(1 + K I))。

所以我的問題是:
1)以這種方式生成因子是否比正常情況下更快(O(sqrt(n))循環方法)?
2)上面給出的代碼可以優化嗎?

第一個最明顯的優化是預分配答案向量。 您確切知道會有多少個因子(因為您已經將公式表示為∏(1 + k i ))。

如果您自己管理堆棧而不是使用遞歸,則將獲得最佳解決方案(每個因素僅需要1個查詢和1個乘法)。

像這樣嗎

int factors_count = 1;
for (int i = 0; i < r; ++i)
{
    factors_count *= 1+exponents[i];
}
ans.resize(factors_count);
ans[0] = 1;
int count = 1;
for (int stack_level = 0; stack_level < r; ++stack_level)
{
    const int count_so_far = count;
    const int prime = factors[stack_level];
    const int exponent = exponents[stack_level];
    int multiplier = 1;
    for (int j = 0; j < exponent; ++j)
    {
        multiplier *= prime;
        for (int i = 0; i < count_so_far; ++i)
        {
            ans[count++] = ans[i] * multiplier;
        }
    }
}

我什至沒有嘗試過編譯它,所以請警告。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM