2022年6月21日leetcode每日一题打卡——67.二进制求和【C语言详解,注释清楚】

一、题目描述及要求

67.二进制求和

题目描述

给你两个二进制字符串,返回它们的和(用二进制表示)。

输入为 非空 字符串且只包含数字 10

示例

示例1

输入: a = "11", b = "1"
输出: "100"

示例二

输入: a = "1010", b = "1011"
输出: "10101"

提示

  • 每个字符串仅由字符 '0' 或 '1' 组成。
  • 1 <= a.length, b.length <= 10^4
  • 字符串如果不是 "0" ,就都不含前导零。

二、解题思路

总的思路:

最简单的思路就是将二进制转化成十进制然后相加再转成二进制,但是可能会有溢出的情况出现。因此还是选择动态分配存储空间,重新申请一个数组空间用来存储每一位相加的和。此时要另外设置一个标志upadate,用于记录是否前一位有进1,因为如果有进1的话相加的结果会有不一样,所以就要分多种情况进行讨论。而且二进制运算与十进制运算一样都是从最后一位相加,所以在访问字符串的时候要从最后一位开始。同时判断那个字符串长,以它为基准申请存储相加后的和的数组空间,接着就进行访问,刚进入循环upadate=0,因为是第一次相加,接着如果要进1就让upadate=1,不用的话就对应的将0/1存入新数组中,接着indexA--和indexB--,如果此时upadate=1则要另外考虑,两者都为1的话就要再次进1,然后留下1,有一个为1则进1,留下0,都为0就不用进1,将upadate赋成0,以此类推一直到a或b有一个空的,接着就是对不空的那个主要是判断是否有进1,否则就是直接赋值。最后要判断upadate是否等于0,如果不等的话意味着最后一次相加的时候还是要进1但是没有没有数需要加了,这时候就需要另外申请一个新的数组,让它的第一位等于1,其余就是从合并后的数组传过来。如果不用的话就将合并的数组的值都赋给新数组,最后返回这个新数组就行。

具体步骤:

1、定义判断是否进一标志upadate,初值为0
2、求字符串长度并且判断是否为空
3、选择其中一个长度为基准申请新的数组存储空间
4、进行遍历与判断
5、最后进行判断来建立新数组并返回

三、具体代码

char * addBinary(char * a, char * b){
    int upadate=0;//是否进1的标志,初始为0
    int lenA=strlen(a);//字符串a的长度
    int lenB=strlen(b);//字符串b的长度
    if(lenA==0&&lenB==0)//如果两个字符串都为空则返回其中任意一个就行
    {
        return a;//等价return b;
    }
    char *combine;//如果两个字符串的长度不一的话就要选择长的那个作为基准申请新的存储空间将二者进行合并
    int combine_len;//合并的字符串的长度
    if(lenA>=lenB)//字符串a比b长
    {
        combine=(char*)malloc(sizeof(char)*lenA);//申请长度为lenA的存储空间作为合并后的存储空间
        combine_len=lenA;//将lenA赋给合并后的字符串长度
    }
    else//字符串b比a长
    {
        combine=(char*)malloc(sizeof(char)*lenB);//申请长度为lenB的存储空间作为合并后的存储空间
        combine_len=lenB;//将lenB赋给合并后的字符串长度
    }
    //index是定位的意思,以下三个分别是指向三个字符串数组的下标
    //因为相加计算是从最后一位进行计算的,所以三个变量的初始值都是长度-1
    int indexA=lenA-1;
    int indexB=lenB-1;
    int indexC=combine_len-1;
    while (indexA>=0||indexB>=0)//当二者有一个不为空时就进入循环
    {
        if((indexA>=0)&&(indexB>=0))//字符串a和b都存在的时候
        {
            if(upadate)//如果前一步已经进过1了
            {
                if(a[indexA]=='1'&&b[indexB]=='1')//此时两位都为1的话则又要进1,同时加上上次进1,应当是为3,最后剩下1,所以相加后这一位应当是1,同时又要进一位,所以upadate还是1
                {
                    upadate=1;
                    combine[indexC]='1';
                }
                else if(a[indexA]=='1'||b[indexB]=='1')//如果只有一个为1,加上上次进1则为2进1,此时因为要进1所以upadate=1,而相加后这一位为0
                {
                    upadate=1;
                    combine[indexC]='0';
                }
                else//两者都为0的话相加就等于进的1,此时不会再进一,所以upadate=0.
                {
                    upadate=0;
                    combine[indexC]='1';
                }
            }
            else//如果前一步不需要进1
            {
                if(a[indexA]=='1'&&b[indexB]=='1')
                {
                    upadate=1;//进一
                    combine[indexC]='0';
                }
                else if(a[indexA]=='1'||b[indexB]=='1')
                {
                    combine[indexC]='1';
                }
                else
                {
                    combine[indexC]='0';
                }
            }
            indexA--;//前移
            indexB--;
        }
        else if(indexA>=0)//只剩下数组a
        {
            if(upadate)//如果后一位进1了
            {
                if(a[indexA]=='1')
                {
                    combine[indexC]='0';
                    upadate=1;
                }
                else
                {
                    combine[indexC]='1';
                    upadate=0;
                }
            }
            //以下两种就是没有进一的情况,a的值就是和的值,因为b数组加完了
            else if(a[indexA]=='1')
            {
                combine[indexC]='1';
            }
            else
            {
                combine[indexC]='0';
            }
            indexA--;
        }
        else//只剩下数组b
        {
            if(upadate)//如果后一位进1了
            {
                if(b[indexB]=='1')
                {
                    combine[indexC]='0';
                    upadate=1;
                }
                else
                {
                    combine[indexC]='1';
                    upadate=0;
                }
            }
            else if(b[indexB]=='1')
            {
                combine[indexC]='1';
            }
            else
            {
                combine[indexC]='0';
            }
            indexB--;
        }
        indexC--;
    }
    int i;
    char *new_combine=(char*)malloc(sizeof(char)*1000);
    if(upadate)//如果相加完后最后一位需要进一
    {
        for(i=0;i<combine_len;i++)
        {
            new_combine[i+1]=combine[i];//将合并后的值赋给新数组
        }
        new_combine[0]='1';//由于到最后一位(字符串的第一位,前面是后序遍历相加)需要进1,所以第一位为1
        new_combine[combine_len+1]='\0';//结束标志
    }
    else //不需要进1,直接将合并数组的值全部赋值到新数组
    {
        for(i=0;i<combine_len;i++)
        {
            new_combine[i]=combine[i];
        }
        new_combine[combine_len]='\0';//结束标志
    }
    return new_combine;
}

猜你喜欢

转载自blog.csdn.net/m0_59800431/article/details/125387607