有關階乘
求n的階乘
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i = 0;
int n = 0;
int ret = 1; //ret 表示階乘
scanf("%d", &n);
for(i = 1;i <=n; i++)
{
ret = ret*i;
}
printf("ret=%d\n", ret);
system("pause");
return 0;
}
ret = ret*i; 這條語句至關重要
求1!+2!+3!+…+n!
代碼1
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i = 0;
int n = 0;
int sum = 0;
int j = 0;
int ret = 1; //ret 表示階乘
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
ret = 1;
for (j = 1; j<= i; j++)
{
ret = ret*j;
}
sum+=ret;
}
system("pause");
return 0;
}
思路說明
for(i = 1;i <=n; i++)
{
ret = ret*i;
}
由第一個獲得的思路 既然此代碼塊可以求階乘
那麼要求1!+2!+3!+…+n! 就讓==條件裏的n是可以從1到n變動的 ==因此想到了再加一層for循環
for (i = 1; i <= n; i++)
{
ret = 1;
for (j = 1; j<= i; j++)
{
ret = ret *j;
}
sum+=ret;
}
在寫代碼的錯誤
缺少了 ret = 1;這一個條件
每次開始一個新的循環之前如果不初始化ret 就會使得ret從上一次的值一直累乘。
如果此時輸入n=3;
例如1!運行後
i=1
ret=1 sum=1
i=2
j=1 ret =ret1=1;
j=2 ret=ret2=2; sum=3
i=3
j=1 ret =ret * 1=2; //錯誤點
j=2 ret =ret * 2=4;
j=3 ret =ret * 3=12; sum=15
未對ret進行初始化 令ret=1
for (i = 1; i <= n; i++)
{
//ret = 1;
for (j = 1; j<= i; j++)
{
ret = ret*j;
}
sum+=ret;
}
代碼2 對代碼1 的優化
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
for (j = 1; j <= n; j++)
{
ret = ret*j;
sum += ret;
}
printf("sum=%d\n", sum);
system("pause");
return 0;
}
代碼1 的問題
從上面可以看出
不論n 等於幾 都要從1開始累乘 一步一步 事實上這加大了運算量
for (j = 1; j <= n; j++)
{
ret = ret*j;
sum += ret;
}
而此種改進方法
利用的是n!=n*(n-1)!
直接在前一步運算的基礎上對 ret*n
簡化了計算量。
詳細解釋
例如1!運行後ret=1 sum=1
n=2
j=1 ret=1
j=2 ret=ret * 2=2; sum=1+2=3
n=3 j=1 ret =ret * 1=1; sum=1
j=2 ret =ret * 2=2; sum=1+2=3
j=3 ret =ret * 3=6; sum=1+2+6=9
寫在最後
爲什麼厲害的人那麼多,今天這個搞得我頭很大。
爲什麼優化的算法想不出來,又或者明明知道有問題,就是找不出問題在哪。真的腦子裏面沒有這個體系啊。
並且我真的覺的越來越難了,原來的二個半小時結束的時候就能消化的差不多,今天真的搞不完了,消化的太慢了。
哎,這個路一點都不好走。
手邊還有四個程序題沒有弄現在十點多了,從六點多到現在真的好累啊。
明天早上起立接着幹。慢慢來,總會看到成果的。
除了對自己說聲加油 沒別的說的了。
今天還有消息說要延遲開學,既然在家裏,就好好把握在家的時間吧。總不能真的一天天玩過去。