LeetCode67_Add Binary

此题是两个二进制字符串相加的问题,自己的版本到最后还有一点问题没有改好,而且不知为何输出总为空字符串,这会儿有点困,打算先参考一份跟自己思路比较一致的代码了。

题目:

Given two binary strings, return their sum (also a binary string).

The input strings are both non-empty and contains only characters 1 or 0.

Example 1:

Input: a = "11", b = "1"
Output: "100"

Example 2:

Input: a = "1010", b = "1011"
Output: "10101"

要注意的问题有几个:

1.两个字符串长短不一,但都是从最后一位开始相加

2.相加时的进位问题,应该用经典的%个位/十位得到,除数为进制数2

3.在最短的字符串相加结束之后,后面的字符串并不是直接赋值,因为还是可能有最后一位的flag=1产生的影响

4.要考虑结束符的问题。假设a="111",则strlen(a)=3,不包括结束符'\0';相对的sizeof(a)=4,包括结束符'\0'

5.while(len--)是挺好用的,但while(len1--&&len2--)不能这样用,因为len2可能不被计算,Len1就被判断为0了

6.动态分配空间应该是strlen返回长度+1,因为还有结束字符。如果直接分配一个包含进位的空间也可以,那就是+2

7.int和char的转换没有那么神秘,int=char-‘0’  char=‘0’+int

 

先贴自己的第一版代码和明显的出错:

char* addBinary(char* a, char* b) {
    int i,d,len,flag=0;
    int len1=strlen(a);
    int len2=strlen(b);
    len=len1>len2?len1:len2;
    char* result=(char*)malloc(len*sizeof(char));//空间至少len+1,应该考虑结束符
    while(len1&&len2){
        result[len-1]=a[len1-1]+b[len2-1]+flag;//忘记了数组中的元素是char而不是int,不能直接这样计算,下面也都出现了这个问题,不再标注了
        if(result[len-1]>=2){
            result[len-1]=result[len-1]-2;
            flag=1;
        }
        else{flag=0;}
        len1--;//这边是考虑了while(len1--&&len2--)不能用,因为len2可能不被计算,Len1就被判断为0了
        len2--;//但是这里忘了同步把len--!!!
    }
    if(len1==len2&&flag==1){
        (char*)realloc(result,(len+1)*sizeof(char));//这句还是没有考虑结束符,也不能len+2,因为len已经不是原来的len值了!
        for(i=len;i>0;i--){//注意,之前len,len1,len2都在循环里被--了,这时的len并不是初始的len,不能这样用了!!
           
result[i]=result[i-1];
        }
        result[0]=1;//没有考虑最后一位结束符的赋值,而且没有注意是char类型
    }
    else{
        if(len1){
            while(len1--){result[len1-1]=a[len1-1];}//这边注意到了len和len1不同步,如果想都用的话,必须同步--;
        }
        if(len2){
            while(len2--){result[len2-1]=a[len2-1];}
        }
    }
    return result;
}
 

再贴自己的第二版代码(返回空字符串,不知道怎么改。。。):

char* addBinary(char* a, char* b) {
    int i,c,d,e,f,len,flag=0;
    int len1=strlen(a);
    int len2=strlen(b);
    len=len1>len2?len1:len2;
    char* result=(char*)malloc((len+1)*sizeof(char));
    result[len]='\0';
    while(len1&&len2){
        c=a[len1-1]-'0';
        e=b[len2-1]-'0';
        if(c+e+flag>=2){
            result[len-1]='0'+c+e+flag-2;
            flag=1;
        }
        else{flag=0;}
        len1--;
        len2--;
        len--;
    }
    if(len1==len2&&flag==1){
        f=strlen(a);
        (char*)realloc(result,(f+2)*sizeof(char));
        for(i=f;i>0;i--){
            result[i]=result[i-1];
        }
        result[0]='1';
        result[f+1]='\0';
    }
    else{
        if(len1){
            while(len1--){result[len1-1]=a[len1-1];}//这时不能直接赋值,还是有进位temp的影响!!!
        }
        if(len2){
            while(len2--){result[len2-1]=a[len2-1];}//这时不能直接赋值,还是有进位temp的影响!!!
        }
    }
    return result;
}

最后是参考的代码,这篇的思路跟自己的思路差不多,所以再修改的话就差不多也是这样了,参考链接:

https://blog.csdn.net/sanmao0816/article/details/45169097

/**
 * 解题思路:另外申请一个数组用于保存相加后的二进制字符串,注意字转整型与整型转字符。注意二进制之间的进位。
 */
char *addBinary(char *a, char *b) {
    int i,j, temp,temp1,lenA,lenB,len;
    char *str;
    lenA = strlen(a);
    lenB = strlen(b);
    len = lenA>lenB?lenA:lenB;
    str= (char *)malloc((len+2)*sizeof(char));//申请的空间要大于最大的字符串长度加1+1,第一个1指字符串相加后可能进位,第二个1指字符串最后的'\0'结束字符

    memset(str,0,(len+2)*sizeof(char));

//Memset 用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘ ’或‘/0’;

例:char a[100];memset(a, '/0', sizeof(a)); memset可以方便的清空一个结构类型的变量或数组。

    j = len-1;temp  = 0;
    for(i=len;i >= 0 && lenA > 0 && lenB > 0; i--){
        *(str+i) = ((*(a+lenA-1)-'0') + (*(b+lenB-1)-'0') + temp)%2 + '0';//  该位取%
        temp = ((*(a+lenA-1)-'0') + (*(b+lenB-1)-'0') + temp)/2;//  进位取/
        lenA--;lenB--;
    }
    if(lenA == 0){//判断谁先结束了,lenA == 0则A先结束,将b字符串赋值给str
        for(; lenB > 0;i--){
            *(str+i) = ((*(b+lenB-1)-'0') +temp)%2 + '0';//这时不是直接赋值,还是有进位temp的影响!!!
            temp = ((*(b+lenB-1)-'0') +temp)/2;
            lenB--;
        }
    }else if(lenB == 0){//b先结束了,则把a字符串赋值给str
        for(; lenA >0;i--){//这里的i还是用之前的值作为初始值;
            *(str+i) = ((*(a+lenA-1)-'0') + temp)%2+'0';
            temp = ((*(a+lenA-1)-'0') + temp)/2;
            lenA--;
        }
    }
    if(temp == 1) {*(str+i) = temp+'0';return str+i;}//若temp进位为1,则赋值给str[i],返回最高位的地址str+i

    return str+i+1;//没有进位的话,返回最高位地址str+i+1;

//这个代码没有重新根据情况分配内存空间,所以最高位不一定是str[0]还是str[1];所以返回的时候不能单一的返回。

}

 

java思路有两种,一种是先将两个字符串逐位从右到左相加的和与进位相加,放入字符数组中。最后等到短的字符串加完之后,留下较长的为加完毕字符串和进位,用以补充字符数组。当然这种解法比较麻烦;另一种是将最短的字符串右端用0补齐,这时两个字符串就等长了,这样就可以逐位相加,最后还有判断是否有进位,如果有进位还得在最左端补上一位1。

以下是思路2的过程代码:

public class Solution {
    public String addBinary(String a, String b) {
        int aLen = a.length();
        int bLen = b.length();
        if(aLen > bLen){//如果字符串a的长度较长
            int gap = aLen - bLen;
            while(gap>0){
                b = 0 + b;//整数+字符串可以直接得到添加了整数元素的字符串,每次都加前面
                gap--;
            }
        }//用0补齐较短的字符串,至两字符串a、b等长
        if(bLen > aLen) {
            int gap = bLen - aLen;
            while(gap>0){
                a = 0 + a;
                gap--;
            }
        }
        int maxLen = aLen > bLen ? aLen : bLen;
        int c = 0, sum = 0;
        String result = "";//注意字符串的声明要首字符大写
        for(int i = maxLen-1; i >= 0; i--) {
            sum = a.charAt(i)+b.charAt(i)-'0'*2+c;//字符串可以直接以.charAt(i)定位符号,不用非转化成字符型数组char[]字符减字符等于整数,比如'1'-'0'=1,后面以数值判断状态,而不是符号。
            if(sum > 1) {
                c = 1;
                sum -= 2;
            } else {
                c = 0;
            }
            result = sum + result;//整数+字符串可以直接得到添加了整数元素的字符串
        }
        if(c == 1) result = 1 + result;//考虑最后如果还存在进位
        return result;
    }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值