iT邦幫忙

0

c++陣列和降冪連乘(n*(n-1)*(n-2)....*1)的運用

如題,小妹百思不得其解,為甚麼計算到n=5就開始錯了><,懇請各路高手幫忙解惑,謝謝!
設陣列是為了使處理的數值範圍更大。
初探程式語言,還請各位多多指教,例如編寫建議等。

#include
using namespace std;
int main()
{
int a,n,v,s,i,b;
int x[500000];
while(true)
{
cout<<"請輸入一個整數 =";
cin>>n;
v=0;
s=1;//紀錄幾位數
x[0]=1;
for(a=1;a<=n;a++)//使123......*n
{
for(i=0;i<s;i++)
{
x[i]=x[i]*a+v;//v用來記錄進位值
v=x[i]/10 ;
x[i]=x[i]%10;
if(v!=0&&i+1==s)
s++;
}
}
cout<<"1x...x"<<n<<"="<<endl;
for(b=s-1;b>=0;b--)//使x陣列降冪排列
cout<<x[b];
cout<<endl;
}
}

看更多先前的討論...收起先前的討論...
weiclin iT邦高手 4 級 ‧ 2017-12-10 23:36:28 檢舉
請查查這些關鍵字: 大數運算, 乘法
小魚 iT邦大師 1 級 ‧ 2017-12-11 03:16:45 檢舉
這好像是階乘吧,階乘不是用遞迴就解決了嗎?
還有,你的程式碼可以用程式碼標籤標起來嗎?
發文時旁邊有個Markdown教學...
weiclin iT邦高手 4 級 ‧ 2017-12-11 17:24:06 檢舉
我上面給錯方向了, 看看海綿寶寶的答案
天天 iT邦新手 5 級 ‧ 2017-12-12 20:45:14 檢舉
感謝各位的回答,下次會注意的。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

2
海綿寶寶
iT邦大神 1 級 ‧ 2017-12-11 08:23:20

我測正常,很好呀...
算30!都不會錯

#include <iostream>

using namespace std;

int main() {
int a,n,v,s,i,b;
int x[500000];
//while(true) {
//cout<<"請輸入一個整數 =";
//cin>>n; 
n=30;
v=0;
s=1;//紀錄幾位數
x[0]=1;
for(a=1;a<=n;a++) {   //使123......*n
   for(i=0;i<s;i++) {
      x[i]=x[i]*a+v;   //v用來記錄進位值
      v=x[i]/10 ;
      x[i]=x[i]%10;
      if(v!=0&&i+1==s)
         s++;
      }
   }
   cout<<"1x...x"<<n<<"="<<endl;
   for(b=s-1;b>=0;b--) {//使x陣列降冪排列
      cout<<x[b];
   }
   cout<<endl;
}
//}
$g++ -o main *.cpp
$main
1x...x30=
265252859812191058636308480000000
看更多先前的回應...收起先前的回應...
weiclin iT邦高手 4 級 ‧ 2017-12-11 17:23:15 檢舉

試了一下他應該是執行第二次輸入以後會出錯, 因為上一次計算的資料沒有清空

原來如此
我用 www.tutorialspoint.com 測試
就偷懶把那個無窮迴圈給 remark 掉
/images/emoticon/emoticon06.gif

小魚 iT邦大師 1 級 ‧ 2017-12-11 19:17:31 檢舉

找到問題點了
/images/emoticon/emoticon12.gif

天天 iT邦新手 5 級 ‧ 2017-12-12 20:46:43 檢舉

謝謝!!!那想再請教,要如何清空資料?我的目的是為了可以重複輸入。/images/emoticon/emoticon06.gif

#include <iostream>
#include <string.h>

using namespace std;

int main() {
int a,n,v,s,i,b;
int x[500000];
while(true) {
    //設定初值
    cout<<"請輸入一個整數 =";
    cin>>n; 
    v=0;
    s=1;//紀錄幾位數
    memset(x, 0, sizeof(x));    //清空 x 陣列
    x[0]=1;
    for(a=1;a<=n;a++) {   //使123......*n
       for(i=0;i<s;i++) {
          x[i]=x[i]*a+v;   //v用來記錄進位值
          v=x[i]/10 ;
          x[i]=x[i]%10;
          if(v!=0&&i+1==s)
             s++;
          }
       }
       cout<<"1x...x"<<n<<"="<<endl;
       for(b=s-1;b>=0;b--) {//使x陣列降冪排列
          cout<<x[b];
       }
       cout<<endl;
    }
}
請輸入一個整數 =1x...x5=
120
請輸入一個整數 =1x...x10=
3628800
請輸入一個整數 =1x...x15=
1307674368000
請輸入一個整數 =1x...x20=
2432902008176640000
請輸入一個整數 =1x...x25=
15511210043330985984000000
請輸入一個整數 =1x...x30=
265252859812191058636308480000000
天天 iT邦新手 5 級 ‧ 2017-12-15 00:34:35 檢舉

再次感謝!

0
JamesDoge
iT邦高手 1 級 ‧ 2023-02-12 12:55:41

你的程式碼的目的是計算階乘的結果,但是在某些情況下會出現錯誤。
這是因為它使用了整數存儲結果,但是整數的存儲空間有限,不能存儲非常大的數字。
解決方法是使用類似於高精度計算的方法來計算階乘的結果。
這需要使用一個陣列來存儲每一位的數字,然後進行適當的運算,以保證結果的正確性。

#include <iostream>
#include <vector>
using namespace std;

// 定義乘法函數
vector<int> Multiply(vector<int> num1, int num2) {
  vector<int> result(num1.size()); // 定義存儲結果的vector
  int carry = 0; // 定義進位值
  for (int i = 0; i < num1.size(); i++) {
    int prod = num1[i] * num2 + carry; // 計算結果
    result[i] = prod % 10; // 取出個位數
    carry = prod / 10; // 計算進位值
  }
  // 如果進位值不為0,則繼續計算
  while (carry) {
    result.push_back(carry % 10);
    carry /= 10;
  }
  return result;
}

int main() {
  int n;
  while (true) {
    cout << "請輸入一個整數:";
    cin >> n;
    vector<int> result(1, 1); // 初始化結果為1
    for (int i = 2; i <= n; i++) {
      result = Multiply(result, i); // 計算階乘
    }
    cout << n << "的階乘是:" << endl;
    for (int i = result.size() - 1; i >= 0; i--) {
      cout << result[i]; // 從高位到低位輸出
    }
    cout << endl;
  }
  return 0;
}

這段代碼使用了 STL 中的 vector,可以很方便地存儲大數字。同時,我們還寫了一個名為 Multiply 的函數,可以對兩個大數字進行乘法運算。

我要發表回答

立即登入回答