首先在编程中会遇到一些很大的数,由于已经给定的数据类型存储范围有限,所以我们应该掌握,如何处理这样的问题。
我这里通过一个计算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;
}
}
代码虽然没给注释,这个比较容易理解,通过先字符串转数,再加法,再保存,通过调用库中的逆序,所以代码看起来更清爽。
总之,关于编程中的大数,还有很多其他操作欢迎大家补充。