1. 程式人生 > >c/c++如何解決大數儲存問題(100的階乘)

c/c++如何解決大數儲存問題(100的階乘)

首先在程式設計中會遇到一些很大的數,由於已經給定的資料型別儲存範圍有限,所以我們應該掌握,如何處理這樣的問題。

我這裡通過一個計算100!的例子給出思路。

想要儲存100的階乘,已有的資料型別肯定無法儲存,我們可以使用字串或者陣列來解決,通過模擬基本計算過程,將

得到的資料儲存到陣列或字串中儲存下來。不多說先給出C語言解法!

#include<stdio.h>
#define max 1000
int a[max]={0};
int main()
{
	a[0]=1;
	for(int i=2;i<=100;i++)
	{
		int carry=0;
		for(int j=0;j<max;j++)
		{
			int s=a[j]*i+carry;
			a[j]=s%10;
			carry=s/10;

		}
	}
	int i=0;
	for(i=max-1;i>0;i--)
	{	
		if(a[i]!=0)
		{
			break;
		}
	}
	for(int j=i;j>=0;j--)
	{
		printf("%d",a[j]);
	}
	printf("\n");
}

這裡是一個非常簡單的思想,通過模擬基本運算過程將每一次更新的進位和資料儲存到陣列中去,然後打印出來,我們可以看出

這樣的方法,有一定的缺陷,因為陣列是給定的,所以前期效率較低,而且陣列長度也得事先給定,所以有一定的記憶體浪費,雖然也不是大問題,至少問題得到了解決!

下面給出c++的一種方法,

#include <assert.h>

#include <stdio.h>
#include<iostream>


#include <vector>


using namespace std;


typedef vector<int> BigInt;



BigInt factorial(int n)

{



  assert(n >= 0 && n <= 10000);



  BigInt result;

  result.push_back(1);

  for (int factor = 1; factor <= n; ++factor) {

    int carry = 0;

    for (auto& item : result) 
   {

      int product = item * factor + carry;

      item = product % 10000;

      carry = product / 10000;

    }

    if (carry > 0) {

      result.push_back(carry);

    }

  }

  return result;

}



void printBigInt(const BigInt& number)

{

  if (number.empty())

  {

    printf("0\n");  // compiles to puts()

  }

  else

  {

    printf("%d", number.back());

    for (auto it = number.rbegin()+1; it != number.rend(); ++it)

      printf("%04d", *it);

    printf("\n");

  }

}



int main()

{

 

  BigInt result = factorial(100);

  printBigInt(result);

}

使用容器來儲存,可以實現10000的階乘,不用實現給定容器大小,顯然已經解決了前面的問題。

再來看一個實現兩給大數相加的問題,這裡也用c++實現了,因為STL庫中的一些演算法及模板還是很好用的。

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
	string s1,s2;
	int len1,len2,lmax;
	while(cin>>s1>>s2)
	{
		len1=s1.length();
		len2=s2.length();

		reverse(s1.begin(),s1.end());
		reverse(s2.begin(),s2.end());

		lmax=len1>len2?len1:len2;
		int temp=0;
		int sum[512];
		int k=0;
		for(int i=0;i<lmax;i++)
		{
			int a=0,b=0;
			if(i<len1)
				a=s1[i]-'0';
			else
				a=0;
			if(i<len2)
				b=s2[i]-'0';
			else
				b=0;
			int result=a+b+temp;
			temp=result>9?1:0;
			sum[k++]=result%10;
		}
		if(temp>0)
		{
			sum[k]=1;
			for(int i=k;i>=0;i--)
			{
				cout<<sum[i];
			}
		}
		else
		{
			k--;
			for(int i=k;i>=0;i--)
			{
				cout<<sum[i];
			}
		}
		cout<<endl;
	}
}

程式碼雖然沒給註釋,這個比較容易理解,通過先字串轉數,再加法,再儲存,通過呼叫庫中的逆序,所以程式碼看起來更清爽。

總之,關於程式設計中的大數,還有很多其他操作歡迎大家補充。

相關推薦

c/c++如何解決大數儲存問題100

首先在程式設計中會遇到一些很大的數,由於已經給定的資料型別儲存範圍有限,所以我們應該掌握,如何處理這樣的問題。 我這裡通過一個計算100!的例子給出思路。 想要儲存100的階乘,已有的資料型別肯定無法儲存,我們可以使用字串或者陣列來解決,通過模擬基本計算過程,將 得到的

C語言——遞迴

很多同學不知道怎麼用遞迴 的方法敲出一個數字的階乘,其實 遞迴就是函式不斷的呼叫自己,具體如下: 程式我簡化了一下 #include<stdio.h> int main() { int m,n; printf("輸入你要計算的階乘的數字:\n"); scanf("%d",&

Python自定義豆瓣電影種類,排行,點評的爬取與儲存

Python 2.7 IDE Pycharm 5.0.3 Firefox 47.0.1 想了想,還是稍微人性化一點,做個成品GUI出來 起因 沒辦法,在知乎預告了要做個GUI出來,吹的牛逼總得自己填坑,下次一定要慎重啊,話說也複習了一下G

計算1^1+2^2+3^3+4^4+5^5+……+20^20 ,大數運算加,java實現

這個題目是明顯的大數運算,不能直接使用int long double 早就超出範圍了,要用陣列結合字串進行處理,分別實現大數的加法和乘法,然後使用實現的加法和乘法寫出來n的n次冪的實現,最後 把它們加起來首先存進來就是要用string來存貯,運算的時候按位運算,charAt(

c/c++如何解決PC蛋蛋源碼下載 大數存儲問題100

stdio.h 語言 例子 字符 使用字符串 ++ c++ 如何 fine PC蛋蛋源碼下載 聯系方式:QQ:2747044651 網址http://zhengtuwl.com 首先在編程中會遇到一些很大的數,由於已經給定的數據類型存儲範圍有限,所以我們應該掌握,如何處理這

關於C#數據的儲存

並且 不同 不同類 long 引用 style 通過 函數 一個數 概念補充: (1)從某個類型模板創建實際的對象,稱為實例化該類型。通過實例化類型而創建的對象被稱為類型的對象或類型的實例。C#程序中,每個數據項都是某種類型的實例。 (2)數據項是數據結構中討論的最小單

編碼原則實例------c++程序設計原理與實踐

組類型 運算 奇怪 head 不能 gui 簡單的 版本 布局 編碼原則: 一般原則 預處理原則 命名和布局原則 類原則 函數和表達式原則 硬實時原則 關鍵系統原則 (硬實時原則、關鍵系統原則僅用於硬實時和關鍵系統程序設計) (嚴格原則都用一個大寫字母R及其編號標識,而

有符號數和無符號數------c++程序設計原理與實踐

效果 進階 str 二進制位 bsp () 都是 有符號 重新 有符號數與無符號數的程序設計原則: 當需要表示數值時,使用有符號數(如 int)。 當需要表示位集合時,使用無符號數(如unsigned int)。 有符號數和無符號數混合運算有可能會帶來災難性的後果。例如

動態內存分配存在的問題內存空洞------c++程序設計原理與實踐

我們 程序 動態 height ++ idt 很多 alt 空間 new的問題究竟在哪裏呢?實際上問題出在new和delete的結合使用上。考察下面程序中內存分配和釋放過程: while(1){ Big* p=new big;  //...... Smal

數值限制------c++程序設計原理與實踐

c++程序 its positive size true 設置 malle 設計原理 硬件 每種c++的實現都在<limits>、<climits>、<limits.h>和<float.h>中指明了內置類型的屬性,因此程序

實現求解線性方程矩陣、高斯消去法------c++程序設計原理與實踐

ipy 類型 cat sys sca solution gaussian 拷貝 img 步驟: 其中A是一個n*n的系數方陣 向量x和b分別是未知數和常量向量: 這個系統可能有0個、1個或者無窮多個解,這取決於系數矩陣A和向量b。求解線性系統的方法有很多,這裏使用一種經典

c++11隨機數------c++程序設計原理與實踐

ber linear 而在 希望 double 元素 light eal 區間   隨機數既是一個實用工具,也是一個數學問題,它高度復雜,這與它在現實世界中的重要性是相匹配的。在此我們只討論隨機數哦最基本的內容,這些內容可用於簡單的測試和仿真。在<random>

C語言實現大數相加思路+程式碼+執行結果

大數相加 思路: 1.先將字串倒序並轉換為數字 2.逐位相加,並存入一個數組e[i]中 3.將得到的結果進行進位處理 4.轉換並把陣列e[i]反轉,迴圈輸出結果 #include<iostrea

C語言遞迴實現n的n!

非負整數n的階乘可以表示為n! (讀作:n的階乘),其定義如下: n! = n·(n - 1)• (n - 2)· …·1 (n大於或等於l),且n = 0時,n! = l 例如,5 ! = 5·4·3·2·1 = 120。 請編寫一個程式,讀入一個非負整數,

淺談C語言的資料儲存

程式由指令和資料組成,C語言程式亦是如此。開發者在編寫程式的時候往往需要根據不同資料的特點以及程式需求來選擇不同的資料儲存方式,那麼在C語言中資料的儲存分為哪些方式呢? C程式大致來講可以分為四個資料區:常量區,靜態去,堆區,棧區。 其中常量區儲存了未被作為初始化使用的字

C語言編程判斷兩個矩陣是否相等n矩陣

運行 can pre \n ++ 8 8 n) i++ pause 主要利用二維數組的模型來存儲矩陣 判斷時一一比較,若有一對元素不相同,則矩陣不相同 源代碼: #include<stdio.h> #include<stdlib.h> int mai

電子書 C#高級編程第9版.pdf

work 並發編程 桌面應用 href 驅動開發 靈活 交互 c# 電子 《C#高級編程(第9版):C# 5.0 & .NET 4.5.1 》由.NET專家的夢幻組合編寫,包含開發人員使用C#所需的所有內容。C#是編寫.NET應用程序的一種語言,本書適合於希望提高編

C++ 何時使用動態分配即使用newkeyword?何時使用指針?

指向 delet 問題 con 擁有 才會 屬性 想要 自己 動態分配 在你的問題裏。你用了兩種方式創建對象。這兩種方式基本的不同在於對象的存儲時間。當運行Object myObject;這句代碼時。它作為自己主動變量被創建,這意味著當對象出了作用域時也會自己主動銷毀。

C#調用Java方法詳細實例

art dem 關系 進行 網上 auto mar ctr 環境 閱讀目錄 C#調用c++ C#調用JAVA方法 C#可以直接引用C++的DLL和轉換JAVA寫好的程序。最近由於工作原因接觸這方面比較多,根據實際需求,我們通過一個具體例子把一個JAVA方法轉換成可以

C++11 Lambda表達式匿名函數

class 訪問 namespace 表達式 span sin clas style col http://www.cnblogs.com/RainyBear/p/5733399.html 匿名函數,好屌的樣子。 Lambda表達式的引入標誌,在‘[]’裏面可以填入‘=’