1. 程式人生 > >求一個數的質因數(1個或n個)

求一個數的質因數(1個或n個)

在做 “容斥原理”  題時經常需要求出一個數的質因子,而且不是所求數的位數很多,就是一次求n多數的質因子。

下面分別給出兩種型別的程式碼,供拋磚引玉。

第一種型別:

用於每次只能求出一個數的質因子,適用於題目中給的n的個數不是很多,但是n又特別大的情況。

#include<stdio.h>
int main()
{
    __int64 n;        
    int i,gs=0;
    int p[100];
    scanf("%I64d",&n);       //輸入所要求的數(可能很大,用int64讀入)
    
    for(i=2;i*i<=n;i++)  
    {
        if(n%i==0)           //若n可以被i整除,則將i加入質因子陣列p中
        {
            p[gs++]=i;
            while(n%i==0)    //n除盡該質因子i,這樣就可以保證下面迴圈的i一定是質因子
            {
                n/=i;
            }
        }
    }
    if(n>1)                  //應對“n=103”這種情況
    {
        p[gs++]=n;
    }
    
    for(i=0;i<gs;i++)
    {
        printf(i+1==gs?"%d\n":"%d ",p[i]);
    }
    return 0;
}

第二種型別:

求出1~n任意給定數的質因子,適用於題目中給的n比較多,但n不是很大的情況。

想法:將給定1~n範圍內所有數的質因子全部求出,存到一個二維陣列中(這裡使用了c++提供的vector容器,比較方便),最後根據所輸入的數輸出其的質因子。

如,分別求出0~104所對應的質因子:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>                    //必須要包含該標頭檔案

using namespace std;
const int M=105;                    //用const定義一個常量M

vector<int>p[M];                    //建立一個vector物件陣列,相當於一個二維陣列
int vis[M];                         //篩素法中用於標記是否走過
 
void init()
{
    int i,j;
    memset(vis,0,sizeof(vis));      //將vis陣列初始化為0
    for(i=0;i<M;i++)                //清空vector陣列
    {
        p[i].clear();
    }
    
    for(i=2;i<M;i++)                //篩選素數,篩素法
    {
        if(!vis[i])                 //判斷是否將i作為質因子
        {
            for(j=i;j<M;j+=i)
            {
                p[j].push_back(i);  //p[j]具有該質因子i,將i加入p[j]的質因子陣列中
                vis[j]=1;           //j不是素數(質數),在下面的迴圈中不作為質因子,標記一下
            }
        }
    }
    
}

int main()
{
    int i,j;
    init();
    for(i=0;i<M;i++)
    {
        printf("%d的質因子為:",i);
        for(j=0;j<(int)p[i].size();j++)  //強制型別轉換,用p[i].size()可知道p[i]的質因子陣列大小(即p[i]有多少個質因子)
        {
            printf("%d ",p[i][j]);       //輸出p[i]的質因子
        }
        printf("\n");
    }
    return 0;
}