求助,分解因子C語言報告|距離問題結束還有14天3小時。提問者:浮雲守護者|獎勵分數:30 |瀏覽量:40次。
給定壹個正整數A,需要分解成幾個正整數的乘積,即a = a1 * a2 * a3 *...* an和1
輸出應該是壹個正整數,表示滿足要求的分解數。
例如,20有四種問題的補充表示法:
把我的想法說清楚就可以了~ ~
謝謝妳
需要指出的是,妳說的是“因式分解”(小學數學學習的內容)而不是中學人才的“因式分解”(後者在計算機上實現要困難得多)。當然,“因式分解”不包括只有壹個因子的情況。
對於這個題目,肯定是中學生競賽題目,沒必要建質數庫。
至少有兩種思維方式。1.根據字典順序逐壹生成各種分解,例如字典順序增加的20:(2,2,5)、(2,10)、(4,5)、(20)的分解,並按此順序生成各種分解。另壹種是按照分解因子的個數逐個生成壹個類,每個類按照字典順序逐個生成。例如,對於20,壹個因子有壹種情況,(20);兩個因子有兩種情況:(2,10)和(4,5);三因素(2,2,5)的情況;有0個案例具有四個或更多因素。
為了節省空間,首先估計不太大的因子數的上限。最簡單的方法是求給定整數A的最小素因子(可假設為正整數),設其為b1,使n=【log _ b1(A)】(以b 1為底數的A的對數四舍五入後表示為n =(在C語言中。
如果妳想精確以節省空間(特別是當A很大時,這是必要的),妳可以先找出所有質因數的數量(包括重復)以確定分解後的最大因數數量,這並不復雜,妳可以這樣確定n。
d = a;
m =(int)(sqrt(D))+1,n=0,c = 2;
while(m & gt;c)
{ if(D % c = = 0)
{ n++;
printf(“% d“,c);
D = D/c;
if(D = = 1)break;
else printf(“,“,c);
m =(int)(sqrt(D))+1;
}
else c++;
if(m & lt;= c){ n++;printf(“% D“,D);打破;}
}
printf(“)\ n整數的質因數個數為%d.\n“,n);
我們討論壹下如何用第壹種思路給出A的全部分解(樓主可以自行考慮第二種思路,難度相同;但是第壹種方法可以在不增加空間開銷的情況下減少壹些重復計算。
由於a最多可以分解為n個因子的直積,因此使用兩個數組來表示每個因子以及每個因子的近似值範圍。用A【n】表示每個因子,用B【n】表示每個因子的範圍。
除了只有壹個因子外,A必須分解成至少兩個因子,A【1】* A【2】,其中A【1】
直到某個k使得A【k】* A【k】》:E【k】使得A【k+1】= E【k】。這樣,得到壹個分解模式:a = a【1】* a【2】*...* a【k】* a【k+1】。
回溯時,讓A【k】自身相加。如果E【k-1】% A【k】= = 0,則得到另壹種分解方法。當A【k】的所有案例都已遍歷時,進行A【k-1】自添加以再次遍歷。
直到A【1】遍歷完所有情況。
遍歷程序只需要修改上面的程序就可以找到質因數的個數。
可行的程序如下:
# include & ltstdio.h & gt
# include & ltmalloc.h & gt
# include & ltmath.h & gt
主()
{ int a,b,c,n,F,F1,D,num,I,I,m;
int *A=NULL,*B=NULL,* E = NULL
printf(“\ n這個程序將獲得給定整數的未排序因子分解的數目。請輸入壹個大於1的正整數。\n數字輸入:“);
scanf(“% d“,& ampa);
if(a & lt;2)
{ printf(\ n輸入錯誤。您輸入的整數無效。\ n ");
返回0;
}
printf(“\ n給定整數%d的質因數如下:\n \t(“,a);
d = a;
m =(int)(sqrt(D))+1,n=0,c = 2;
while(m & gt;c)
{ if(D % c = = 0)
{ n++;
printf(“% d“,c);
D = D/c;
if(D = = 1)break;
else printf(“,“,c);
m =(int)(sqrt(D))+1;
}
else c++;
if(m & lt;= c){ n++;printf(“% D“,D);打破;}
}
printf(“)\ n整數的質因數個數為%d.\n“,n);
if(n = = 1)
{ printf(“\ n您輸入的整數是壹個質數。未排序因式分解的個數是1。\ n ");
返回1;
}
a =(int *)malloc(sizeof(int)* n+1);
if(A = = NULL)
{ printf(\ n錯誤。內存空間不足。\ n ");
返回0;
}
b =(int *)malloc(sizeof(int)* n+1);
if(B = = NULL)
{ printf(\ n錯誤。內存空間不足。\ n ");
返回0;
}
e =(int *)malloc(sizeof(int)* n+1);
if(E = = NULL)
{ printf(\ n錯誤。內存空間不足。\ n ");
返回0;
}
e【0】= A,A【0】= 2,A【1】= 1,num = 0;
b【1】=(int)(sqrt(E【0】))+1;
I = 1;
while(I & gt;0 & amp& amp我& lt=n)
{ F=0,F 1 = 0;
//printf(“\ n I = % d,B【I】= % d,E【I-1】= % d,A【I-1】= % d .“,I,B【I】,E【I-1】,A【I-1】);
//if(I & gt;n){ printf(“\ n錯誤。我= % d & gtn=%d.\n“,I,n);返回-1;}
for(A【I】++;a【I】& lt;b【I】;a【I】++)
{//printf(“\ n A【I】= % d,“,A【I】);
if(E【I-1】% A【I】= = 0)
{ //printf(“有效。);
E【I】= E【I-1】/A【I】;F++,f 1++;
if(E【I】& lt;A【I】* A【I】& amp;& ampf 1 = = 0)//E【I】!=1
{ printf(“\ n有效的因式分解:%d=“,A);
if(I & gt;0)printf(“% d“,A【1】);
if(I & gt;1)for(I = 2;我& lt我;i++)printf(“* % d“,A【I】);
printf(“* % d“,E【I】);
num++;
f = 0;
}
else // F1!= 0 | | E【I】》;= A【I】* A【I】
{ B【I+1】=(int)(sqrt(E【I】))+1;A【I+1】= A【I】-1;i++;打破;}
}//end if(E【I-1】% A【I】= = 0)
//else printf(“無效。);
} //結束循環I
if(F = = 0。& ampf 1 = = 0)//E【I-1】不能被所有可能的A【I】整除。
{ printf(“\ n有效的因式分解:%d=“,A);
if(I & gt;1)
{ printf(“% d *“,A【1】);
for(I = 2;我& lt我;i++)printf(“% d *“,A【I】);
}
printf(“% d“,E【I-1】);
num++,I-;
}
}//while(I & gt;0)
printf(“\ n給定整數的未排序因式分解數為%d.\n“,num);
免費(A);
免費(B);
免費(E);
返回1;
}
由gcc編譯,當輸入20時,結果如下:
這個程序將得到壹個給定整數的未排序因子分解的個數。請輸入壹個大於1的正整數。
數字輸入:20
給定整數20的質因數如下:
( 2, 2, 5 )
整數的質因數的個數是3。
壹個有效的因式分解:20=2*2*5
有效的因式分解:20=2*10
壹個有效的因式分解:20=4*5
壹個有效的因式分解:20=20
給定整數的未排序因子分解數為4。
當輸入36時,結果如下。
這個程序將得到壹個給定整數的未排序因子分解的個數。請輸入壹個大於1的正整數。
數字輸入:36
給定整數36的質因數如下:
( 2, 2, 3, 3 )
整數的質因數的個數是4。
壹個有效的因式分解:36=2*2*3*3
壹個有效的因式分解:36=2*2*9
壹個有效的因式分解:36=2*3*6
有效的因式分解:36=2*18
壹個有效的因式分解:36=3*3*4
有效的因式分解:36=3*12
壹個有效的因式分解:36=4*9
壹個有效的因式分解:36=6*6
壹個有效的因式分解:36=36
給定整數的未排序因式分解數為9。