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;
	}
}

代码虽然没给注释,这个比较容易理解,通过先字符串转数,再加法,再保存,通过调用库中的逆序,所以代码看起来更清爽。

总之,关于编程中的大数,还有很多其他操作欢迎大家补充。

猜你喜欢

转载自blog.csdn.net/Dachao0707/article/details/82048001