zoukankan      html  css  js  c++  java
  • 高精加法

    原题链接:https://www.luogu.org/problemnew/show/P1601

    概要:

    计算A+B(高精度)

    这道题其实就是求一个高精度加法的问题,很简单,关键还是要对高精度算法有清晰明确的理解。

    下面我们先来说一说高精度算法:

    高精度存在的意义是什么呢?说白了就是为了运算大数据,众所周知,c/c++里面定义数据类型最大的,也就是使用long long型,那也只能存放64位二进制数,那如果遇到如题示例中的超大数据就无能为力,只能望洋兴叹了。。。

    这时候该如何处理呢。。。一般武侠玄幻小说里面都会说到一个词,一旦提到这个词的人物莫不是狂拽酷无敌屌炸天,这个词呢就是:返璞归真。我们学习之路也是需要一个返璞归真的过程的。大家还记得我们在小学初学计算加法时的方法吗?竖式算法,这是最基础但也是最好用的方法,因为它的包罗万象,有它在我们可以计算任何我们想要的数据。

    那我们是不是可以设计程序,让电脑按照这种方式运算呢。于是在人类无穷探索力之下,高精度算法诞生了。

    我们先来复习一下竖式计算:

               1 2 3 4 5 6 7 8 9

            + 9 8 7 6 5 4 3 2 1

    ———————————————

            1 1 1 1 1 1 1 1 1 0


    我们既然没有足够大的数据类型去存放这两个数据,那该怎么让计算机识别这个数据呢,这时候我们就应该用char数组去存储数据了。为什么是char而不是int呢,因为char的大小比较适合。

    接下来我们会发现竖式运算是右对齐的,同时也是从右边开始运算的,但是我们不知道输入数据的长度,这时候我们该怎么办呢?其实很简单,我们可以直接将数组倒置,也就是让a[0]为输入数据的最后一位,这样虽然不了解数据的长度,但我们只要从0开始依次向后就好。

    接下来我们需要做一件很容易忽略的事,毕竟我们定义的是char,如果我们输出的ans是int型,那么我们在倒置数组的时候,还有一件事要一并完成。那就是(-'0'),也就是减去0的ASCII码,即-48,这样一来我们就可以让数据本身等于本身,也就是本来0字符串在整型里代表的是48,在我减去‘0’最后,0字符串代表的就是0本身了。这样操作我们在输出的时候就可以很方便的表达。

    然而你以为这样就可以高枕无忧了吗?大错特错!题目在这里设置了一个巨型天坑,那就是输入的数据竟然会有前置零!就是会有类似001这样的数,好恼火有没有!这个点很简单就可以处理掉了,关键就是要get到它啊。。。。具体处理方法就是用strlen函数计算出数据长度,从最后一位开始,直到遇到第一个不为零的数,遇到一个零就让总长度减1,一直减一直减,这样就可以去除前置0的影响了。

    为了获得答案,首先我们需要知道答案的长度,这个计算机显然是无法判断的,但我们知道一点,那就是既然是加法,答案的长度就绝对不会小于其中的任意一个数的长度,所以我们先让答案的长度等于较长的个该加数的长度,具体的操作我们下面再说。

    现在知道了answer的长度len(暂时),我们就该进行竖式算法的加减了,到了这里其实反而最简单了,我们只要令ans[i]=a[i]+b[i],再判断ans[i]时候超过十,如果超过了,我们直接让ans[i+1]+=1;这样循环,介于答案长度到这里也就不言而喻了,当ans[len-1]大于10的时候,就说明需要改变长度了,只要让len++就ok了。

    这时候还有一个特例需要解决,就是当数据是0 0是,我们会把数据当做前置0全部去掉,这时候输入数据长度就是0,我们需要加上len==0时,输出‘0’这样一个操作就ok,

    最后输出结果一个循环就行,因为前面我们已经进行过-‘0’操作,放心大胆的输出%d,答案一定没毛病。

    最后因为是多住组输入,我们在输出结果后还需要对三个数组进行清零,我推荐使用memset函数,方便合适,实在是清理数组,必备良药。


    文字来源:https://blog.csdn.net/k_x_k_baoqian/article/details/79793513

    #include<bits/stdc++.h>
    using namespace std;
    string s1,s2;
    int a[10001],b[10001],c[10001];
    //c为文字中的ans数组
    int main() { cin>>s1; cin>>s2; int l1=s1.length(); int l2=s2.length(); for(int i=0; i<l1; i++) { a[l1-i]=int(s1[i]-48); } for(int i=0; i<l2; i++) { b[l2-i]=int(s2[i]-48); } int l3=1; int t=0; while(l3<=l1||l3<=l2) { c[l3]+=a[l3]+b[l3]+t; t=c[l3]/10; c[l3]%=10; l3++; } c[l3]=t; if(c[l3]==0) l3--; for(int i=l3; i>0; i--) cout<<c[i]; return 0; }
  • 相关阅读:
    编译原理知识点整理
    LeetCode 3.无重复字符的最长字串
    LeetCode 2.两数相加
    LeetCode 1.两数之和
    《硅谷之火》中的个人计算机梦
    Linux常用命令行指令(持续更新~)
    idea常用快捷键(随时更新~)
    解决idea中使用maven创建spring mvc项目时创建过慢问题
    spring实战第二章小记-装配bean
    HTML5 Video播放服务端大文件
  • 原文地址:https://www.cnblogs.com/yigejuruo/p/10400412.html
Copyright © 2011-2022 走看看