数组形式的整数加法(详细思路详解和代码实现)

数组形式的整数加法(详解)

题目:

数组形式的整数加法

整数的 数组形式 num 是按照从左到右的顺序表示其数字的数组。

  • 例如,对于 num = 1321 ,数组形式是 [1,3,2,1]

给定 num ,整数的 数组形式 ,和整数 k ,返回 整数 num + k数组形式

示例 1:

输入:num = [1,2,0,0], k = 34
输出:[1,2,3,4]
解释:1200 + 34 = 1234

示例 2:

输入:num = [2,7,4], k = 181
输出:[4,5,5]
解释:274 + 181 = 455

示例 3:

输入:num = [2,1,5], k = 806
输出:[1,0,2,1]
解释:215 + 806 = 1021

注意:

对于这道题目来说,不可采用,将数组里的数拿出来去x10,x100,x1000这样子去做,因为当数组大道一定正度的时候,int类型无法存放太大的数,即便用long long 类型也不行

image-20240430235432737

这题实际上想考的是——大数相加

分析:

其实这道题目就是用我们之前小学的加法来做就行了。

如图所示:

image-20240430235759438

先看第一位:4 + 1 = 5

在看第二位:7 + 8 = 15 大于10 进1

第三位: 2 + 1 = 3 再+ 第二位进的1 = 4

所以就是 455。

思路:

  1. 首先我们要知道两个相加的数的位数
  2. 对于数组来说,位数就是数组的长度 也就是numsize
  3. 对于k数字来说,位数需要我们自己去算
  4. 知道了位数之后,我们就需要给新数组申请内存空间
  5. 空间的大小是两个数的最大位数 + 1 (n位数相加可能是n位数,也可能是n+ 1位数)
  6. 并且要相加多少次,也是取决于最大位数。
  7. 判断相加之后是否大于10,大于10要记得进1处理
  8. 由于我们不知道相加之后的数是否是n+1位数,因此采取下标0存储数据。
  9. 等到所有的位数相加完后,存到新数组之中后,再将数组进行逆序处理

代码:

int* addToArrayForm(int* num, int numSize, int k, int* returnSize) 
{
    // 要想进行相加  我们需要知道两个加数的位数  数组的位数就是numSize
    // 那么我需要知道k是多少位的数字
    int knum = k; // 让knum接受k的值 去进行操作  不然后面找不到k了
    int kSize = 0; // kSize就是k这个数字的位数
    while(knum)
    {
        kSize++;
        knum/=10;
    }

    // 我们知道,每次相加都是位跟位之间的相加  比如个位加个位  十位加十位......
    // 我们如果想知道要相加多少次  那就需要最大的加数的位数
    int len = numSize < kSize ? kSize : numSize; // len此时就是最大的数的位数
    // 知道了相加的次数 我们需要一个新的数组 来存放我们相加的值  
    // 由于这个数组的空间是不确定的,因此我们需要动态申请空间 (malloc)
    int* retArr = (int*)malloc(sizeof(int) * (len + 1));  
    //  len+1 是因为 n位数+n位数 可能是n位数 也可能是n + 1位数

    int numnext = 0; // 用于记录位数相加是否需要进 1
    int reti = 0; // 用于retArr新数组的下标记录

    // 我们首先要进行个位数的相加,那我们得先将个位数取出来
    int ni = numSize - 1; // 数组的最后一个元素就是 数组的个位数.  
    //numSize - 1 就是最后一个元素的下标, ni就是数组的个位数
     //后面对ni - 1就可以取到十位,以此类推

    // 有了新数组retArr 我们就要相加
    while(len--) // 前面我们说了len就是最大位数,也就是相加的次数
    {
        int N = 0;
        if(ni >= 0) // 如果数组的位数小于k的位数,那么后面的ni一定会小于0,就会造成越界访问
        {
            N = num[ni]; // 如果ni小于0 就说明这个地方的位数的值为0就好
        }
        // 对位数进行相加
        int ret = N + k % 10 + numnext; // 如果有进位就加上进位,没有进位+0也不影响
        // 这里要注意ni是否越界的问题
        k /= 10; // 相加完之后 让k少去个位数 这样下一次k % 10 取得就是十位数 ,以此类推
        ni--; // 这样ni指向的就是数组的下一位数

        // 判断位数相加是否大于等于10  
        if(ret >= 10)
        {
            // 大于10 要在下一位相加的时候进1
            numnext = 1;
            ret -= 10; 
        }
        else
        {
            numnext = 0; // 要置为0 不然如果numnext = 1  后面有位数相加 就会导致多进一个1
        }
        // 由于不清楚n位数加n位数 到底是n位数 还是n+1位数  这个下标不好从后面开始定位
        // 因此这里采取从下标0开始存储,等相加完,存储完之后 在循环外面进行数组的逆序 
        retArr[reti] = ret;
        reti++; 
    }

    // 这里还有一个问题  如果数组和k的位数相同,都是n位数。那么如果 加起来是n+1位数,这个时候的n+1位就没有存下来
    if(numnext == 1)
    {
        retArr[reti] = 1; // 给n+1位 一个进位 也就是1 
        reti++; // 记得要让reti++ 及时改变数组的长度,也就是元素个数,reti++之后的reti记载的是元素个数
    }

    // 对retArr进行逆序
    int left = 0;
    int right = reti - 1; // reti记载了我们结果的位数 right是该数组的最后一个元素的下标
    while(left < right)
    {
        int temp = retArr[left];
        retArr[left] = retArr[right];
        retArr[right] = temp;
        left++;
        right--;
    }

    *returnSize = reti;
    return retArr; // 注意了 返回这个数组的首元素地址,但是接口不知道你的数组长度
}

要注意的一些点:

  1. 首先就是位数相同的时候,比如n位数+n位数,如果是n+1位数,我们的循环是解决不了问题的

代码是这样解决的:

    // 这里还有一个问题  如果数组和k的位数相同,都是n位数。那么如果 加起来是n+1位数,这个时候的n+1位就没有存下来
    if(numnext == 1)
    {
        retArr[reti] = 1; // 给n+1位 一个进位 也就是1 
        reti++; // 记得要让reti++ 及时改变数组的长度,也就是元素个数,reti++之后的reti记载的是元素个数
    }
  1. 如果是数组的位数小于k的位数的时候,数组会有越界访问的情况

如图所示:

image-20240501022415080

我们的代码是这样解决的:

 int N = 0;
        if(ni >= 0) // 如果数组的位数小于k的位数,那么后面的ni一定会小于0,就会造成越界访问
        {
            N = num[ni]; // 如果ni小于0 就说明这个地方的位数的值为0就好
        }
  1. 要记得返回我们的数组长度

题目中的函数形参中有给到int* returnSize。

*returnSize = reti;
  • 21
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值