• 洛谷P1601


    题目见P1601 A+B Problem(高精) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

    1. 问题分析

            加法计算问题应该和在界面输出“Hello,world!”是一个难度级别,但是问题在于受限于原始数据类型的限制,无法进行大数据的精确的加法运算。即使双精度浮点数计算近似值,最大数差不多是308位数字,超过这个位数也是无法计算的。那这样就有问题了,利用原始的数据类型是无法存储一个任意大的整数的,需要自定义类型和运算和实现。Java中就有这种类型,python的加法也可以实现。那么如果用C++来写的话,应该如何去做呢?(做法很多,美丽的做法也跟多,我只是从个人角度出发来考虑这个问题)

            其实想法很简单,我们用数组来表示一个整数,有多少位,数组的长度就设置多少完了。比如存储123.

    1. #include
    2. using namespace std;
    3. int main(){
    4. int a[3] = {1,2,3};
    5. return 0;
    6. }

              这样以来,我们就可以通过两个数组来表示两个整数,通过两个数组来利用加法的运算规则来进行计算了。

    2. 计算步骤

    2.1  输入问题

            题目输入的是两个整数,我们用什么来接收这两个数字呢?任意长度的,我们可以用字符串来接收这两个整数。

    1. #include
    2. using namespace std;
    3. int main(){
    4. string a, b;
    5. cin >> a;
    6. cin >> b;
    7. return 0;
    8. }

    2.2 字符串转化为整数数组

    2.2.1 位置关系

            我们需要将字符串的最后一位,也就是个位数放置在整数数组的第0个位置,将倒数第二个位置的字符转为整数放置在整数数组的第1个位置,一次类推。

    2.2.2 类型转化

            字符串(string)实际上是一个字符数组,字符串的每个位置是一个char类型,char类型采用ascii来存储,acsii对于0~9的数字是连续存储的,因此只需要用字符串每个位置的char类型减去字符0既可。

    2.2.3 代码实现

    1. #include
    2. using namespace std;
    3. void str2char_arr(string str, int a[]){
    4. int n = str.size();
    5. for (int i = n-1; i>=0; i--){
    6. a[n-i-1] = str[i] - '0';
    7. }
    8. }
    9. void display(int a[], int n, bool reverse){
    10. for (int i = 0; i < n; i++){
    11. if (reverse == true){
    12. cout << a[n-1-i];
    13. }else{
    14. cout << a[i];
    15. }
    16. }
    17. }
    18. int main(){
    19. string str1, str2;
    20. int a[500];
    21. int b[500];
    22. cin >> str1;
    23. cin >> str2;
    24. str2char_arr(str1, a);
    25. str2char_arr(str2, b);
    26. display(a, str1.size(), false);
    27. return 0;
    28. }

    2.3 定义加法运算

            加法运算的规则如下:

            1. 从左到右依次计算

            2. 两个数组的数字对应位置相加,加上上一次的进位(上次进位为上次的和除以10的商),然后对10取余。

            注意:可以根据题目中数据的大小约束,设置较大的数组,并且两个数组的大小一致,这样有点浪费空间和时间。后面可以用可变数组来优化。

    1. #include
    2. using namespace std;
    3. void str2char_arr(string str, int a[]){
    4. int n = str.size();
    5. for (int i = n-1; i>=0; i--){
    6. a[n-i-1] = str[i] - '0';
    7. }
    8. }
    9. void display(int a[], int n, bool reverse){
    10. for (int i = 0; i < n; i++){
    11. if (reverse == true){
    12. cout << a[n-1-i];
    13. }else{
    14. cout << a[i];
    15. }
    16. }
    17. }
    18. void add(int a[], int b[], int c[], int n){
    19. int t = 0;
    20. for (int i = 0; i < n; i++){
    21. t += a[i] + b[i];
    22. c[i] = t%10;
    23. t /= 10;
    24. }
    25. }
    26. int main(){
    27. string str1, str2;
    28. int a[501];
    29. int b[501];
    30. int c[501];
    31. int n = 501;
    32. cin >> str1;
    33. cin >> str2;
    34. memset(a, 0, sizeof(a));
    35. memset(b, 0, sizeof(b));
    36. str2char_arr(str1, a);
    37. str2char_arr(str2, b);
    38. add(a, b, c, n);
    39. while(c[n-1] == 0 && n > 1){
    40. n--;
    41. }
    42. display(c, n, true);
    43. return 0;
    44. }

    2.4 逆序输出

            计算的时候从个位数开始计算,个位数的索引小,所以输出的时候需要逆序输出。另外就是要从第一个不为0的数字输出。

    3. 优化

          这只是一个初级版本,优化空间很大。

  • 相关阅读:
    数据结构·顺序表
    (c语言)移位操作符
    盘点国内主流数字孪生厂商!你了解几家?
    ARM系列 -- 虚拟化(一)
    在win10上格式化Linux启动盘
    计算机组成原理-中央处理器详细讲解(持续更新中)
    JVM调优的GC日志观察解读
    KS003基于JSP和Servlet实现的商城系统
    分布式事务解决方案
    Elasticsearch索引中数据的增删改查与并发控制
  • 原文地址:https://blog.csdn.net/qshbbh/article/details/133838194