扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
目录
万秀ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为成都创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18982081108(备注:SSL证书合作)期待与您的合作!引言:
一、高精度加法:
二、加法解释:
三、高精度减法
四、减法解释:
第一次写代码博客,欢迎大家......
废话不多说,开始吧。
我们知道,在c中,int类型数量级为1e9,long long类型的数量级是1e18,如果我们需要处理大型数据,如1e1000,1e5000,即使使用unsigned long long也无可奈何,我们就需要引入大数据处理算法,下面是以加减法的例子:
一、高精度加法:首先先上代码:
#include#include#includeint max(int la, int lb);
int main(void)
{
char s1[505], s2[505];
//*每一位数字存成字符,而不是用ull
int a[505] = {0}, b[505] = {0};
int c[505] = {0};
scanf("%s %s", s1, s2);
int la, lb, lc;
la = strlen(s1);//*差不多是位数的意思
lb = strlen(s2);
int i;
for ( i = 0; i< la; i++)
{
if (s1[i] == '0')
{
continue;//*输入的大数据如果有前导0,则不管之
}
a[la - i] = s1[i] - '0'; //*-‘0’是转换字符为数字的意思,这里la-i是把整个输入的大数据倒置,方便做加法运算,不然1234+827不倒置直接加,不能保证个位加个位,十位加十位,s1是4321,s2是728,这样从前到后,依次加法,就能保证对位加法
}
for ( i = 0; i< lb; i++)
{
if (s2[i] == '0')
{
continue;
}
b[lb - i] = s2[i] - '0';//*还需要注意的是,当i==0,lb-i是lb,当i==lb-1,lb-i就是1,也就是说a和b数组从【1】开始记录大数据,【0】值为0
}
lc = max(la,lb) + 1;//*针对数组从1开始记录,lc还要加1,表示加法之后的大位数+1
for ( i = 1; i<= lc; i++)
{
c[i] += a[i] + b[i];//*先无脑加
c[i+1] = c[i] / 10;//*然后进位
c[i] %= 10;//*如果没进位,那没事,进位了,就要取余10,防止炸掉,你当然不想个位数存在10这样的数字
}
while (c[lc] == 0 && lc >1)
{
lc--;//*如果c数组最高位是0,而且lc>1//*(c是从【1】开始记录的,【0】不能算上)
}
for ( i = lc; i >= 1; i--)
{
printf("%d", c[i]);//*输出就完事了
}
return 0;
}
int max(int la, int lb)
{
if (la >lb)
{
return la;
}else
{
return lb;
}
}
二、加法解释:1.核心:用数组接受大数据
2.我们先用字符数组接受输入的大数据,字符数组的长度是大数据的位数,比如1234,就是四位,方括号就是4.用strlen就可以知道整个大数据的位数,得到的位数也是数组大下标的值还要+1
3.建三个int类型数组,用来进行数字操作,ab数组是两个需要加和的大数据,c数组是做加法之后的大数据
4.在前面两个for中,我们是将字符数组倒置之后再赋值给int数组,为什么这么做,我们看,如果两个大数据的位数都是一样的,那么做和只需要个位加个位,十位加十位对应相加即可,但是如果出现1234+827这样的数字?这两个大数据在字符数组中保存时,1234分别是【0】【1】【2】【3】,827是【0】【1】【2】,那么如果做加法就要用8【0】+ 2【1】,2【1】+ 3 【2】,这样是在进行错位加法,不利于代码实现,如果我们将字符数组倒置,4321分别对应【0】【1】【2】【3】,728分别对应【0】【1】【2】,这样加法的时候,就能做到4【0】+ 7【0】了,具体的实现是s1数组的大下标赋值给a数组0下标,依次类推,同理s2与b数组
5.然后就是深入理解加法的实现,低位4+7,产生了进位1,那么高位就要接收这个1,用除号实现,同时,还要保证低位值不能超出10,用取余实现
6.做和之后的位数是原来两个数据位数大值还要+1,这时候的位数lc就是做和之后的数组最后一个数字的下标,这点需要理解,这是由于字符数组倒置赋值给ab数组造成的,数据从【1】开始记录。
7.值得注意的是,ab数组接收倒置后的字符数组,是从【1】开始的,【0】值应为0,所以在后面做和后的c数组也是从【0】开始的,做和之后的数组是倒置的,那么打印的时候就要倒序打印,打印到【1】结束,不打印【0】
8.特殊情况是,当出现0+0时,lc就是2了,那么c数组【0】【1】【2】分别是0,0,0,如果按正常情况倒序打印,会打印出00,此时需要循环判断,如果大下标lc是0,就利用lc--删除之,一直到lc为1或者出现非0数字时中止
三、高精度减法加法是减法的基础:
废话不多说,先上代码:
#include#include#includeint max(int la, int lb);
int main(void)
{
char s1[505], s2[505];
int a[505] = {0}, b[505] = {0};
int c[505] = {0};
scanf("%s %s", s1, s2);
int la, lb, lc;
int len = 0;
la = strlen(s1);
lb = strlen(s2);
if (la >lb)
{
len = 1;
}
int i;
for ( i = 0; i< la; i++)
{
if (s1[i] == '0')
{
continue;
}
a[la - i] = s1[i] - '0';
}
for ( i = 0; i< lb; i++)
{
if (s2[i] == '0')
{
continue;
}
b[lb - i] = s2[i] - '0';
}
lc = max(la,lb) + 1;
int flag = 0;
for ( i = 1; i<= lc; i++)
{
if (len == 1)
{
c[i] = a[i] - b[i];
}else
{
c[i] = b[i] - a[i];
}
if (flag == 1)
{
c[i]--;
}
if (c[i]< 0)
{
c[i] += 10;
flag = 1;
continue;
}
flag = 0;
}
while (c[lc] == 0 && lc >1)
{
lc--;
}
for ( i = lc; i >0; i--)
{
printf("%d", c[i]);
}
return 0;
}
int max(int la, int lb)
{
if (la >lb)
{
return la;
}else
{
return lb;
}
}
很容易发现,其实代码大部分与大整数加法是一样的,只是减法的实现有所不同
四、减法解释:1.我们使用len模拟一下被减数和减数的情况,1和0代表不同的大减小情况
2.flag初始值为0,代表没有借位,一旦产生借位,flag为1
3.低位照常减法,如果减法得到负数,则向高位借10,flag为1,continue进入下次循环,判断flag为1,先把高位减一
4.如果减法没有得到负数,重置flag为0
5.减法的实现是关键要点
第一次发文不易,喜欢的话多多点赞支持,希望我的经验能够帮到你们。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流