有一段时间没和大家更新算法,今天来和大家研究一下,简单高精度加法。
首先,例:求A+B的值。
这个应该很简单::
cin>>a;
cin>>b;
cout<<a+b
对于类型范围内的都可以用。但如果a和b都是5000位以内或者更高的呢,这个朴素求法,就gg了。
由于待处理的数据超过了任何一种数据类型所能容纳的范围,因此必须采用数串形式传输入,并将其转化为整形数组,其转化方式是该数字字符减去
“0”或者48即可该数组的每一个元素对应一位十进制数,由其下标顺序指明位序号。例如计算1234567890+987654321的值。
初始化如图所示。
对整型数组a[]和b[]按算术运算规则进行运算之前,需要用变量记录两组整数数组的最大元素个数,即最大位数,这是因为由于高精度运算的结果
可能使得数据长度发生增减(最高位进位)。
运算过程如图所示。
不知道大家看到这有没有点头绪,不妨动手写写看。
给点提示:
写一个初始化整型数组函数;
int add( )
{
}
再写一个字符串转为整型数组函数:
void init( )
{
}
最后写一个输出到相加的结果函数:
void output( )
{
}
最后贴上源代码:
#include<iostream>
#include<fstream>
#define MAXN 5001
using namespace std;
int add(int x[],int y[],int z[],int len)
{
int i,j,r;
for(j=0;j<len;++j) //从下标0开始逐位相加到len-1
{
z[j] += x[j]+ y[j]; //相加结果存到z[]
for(i=j;i<len;++i)
{
if(z[i]>=10) //如果当前位数的值超过了10,则要进位处理
{
z[i+1] += z[i]/10; //此处如改为++z{i+1],效率更高
z[i] -= 10; //或者是z[i]%=10,但速度稍慢
if(z[len] > 0)
len++;
if(z[i+1] < 10) //小优化
break;
}
}
}
return len; //返回位数
}
void init(int x[],string str,int len) //字符串转为整型数组
{
for(int i=0;i<len;i++)
x[len-i-1] = str[i]-'0'; //倒序转换
}
void output(int z[],int len) //输出到相加的结果
{
for(int i=len-1;i>=0;i--)
cout<<z[i];
cout<<"\n";
}
int main()
{
string str1,str2;
int a[MAXN]={0},b[MAXN]={0},z[MAXN]={0}; //初始化为0
int la,lb,len;
cin>>str1;
cin>>str2;
la = str1.size();
lb = str2.size();
init(a,str1,la); //初始化整型数组
init(b,str2,lb);
if(la >= lb) //确定a和b的最大位数
len = add(a,b,z,la); //取最长位la
else
len = add(b,a,z,lb); //取最长位lb
output(z,len);
return 0;
}
测试数据:1234567890+123456789
结果:
测试数据:123456789123456789123456789123456789123456789+987654321987654321987654321987654321
结果:
希望大家能够举一反三,减法,乘法,除法也都能写出来!
下次为大家带来背包问题的算法讲解。