一、题目
二、题目分析
关于这个题目,相信很多人(包括我)本能反应是先将字符串转换为二进制数,然后再对其求解,最后再将求解的结果转换为字符串返回。
这里我们需要注意的题目并没有说明二进制字符串的长度,所以不管我们定义多大的变量去存储字符串转换成的结果,都有可能存在数据溢出的问题,并且,这样的方法效率会很低,因为我们需要将两个字符串转换为两个整数,在将相加后的结果转为为字符串。
在这里我们可以直接使用字符串模拟二进制加法,然后将得到的结果直接保存到返回数组中。
这里首先将数据对齐,然后按位依次相加,有进位就记录下来,若字符串的位不够了,则补0进行运算。
例如“ 1011011 “ 和 “ 1011 ”相加,“ 1011 ”相对 “ 1011011 ”明显的缺位,需要我们补0进行计算,补充完之后得到下图所示结果。
char * addBinary(char * a, char * b){
int len_a = strlen(a);
int len_b = strlen(b);
int len = (len_a > len_b) ? (len_a) : (len_b);
char *arr = (char *)malloc(sizeof(char) * (len + 2));
//len + 2 的原因是返回的字符串有一个结束符,并且要考虑到进位的关系预留一个位
arr[++len] = '\0'; //++len是因为申请的考虑到进位的关系,所以结束符理应后移一位
char carry = '0'; //进位标志位
char pa = '0'; //a字符串当前值
char pb = '0'; //b字符串当前值
while (len > 1 || carry == '1') //len = 2时,就是无数据溢出的情况,1的时候是溢出一位了
{ //重后往前计算
pa = len_a > 0 ? (a[--len_a]) : '0'; //超出a字符串长度补‘0’
pb = len_b > 0 ? (b[--len_b]) : '0'; //超出b字符串长度补‘0’
arr[--len] = pa ^ pb ^ carry; //得到当前位数据
carry = (pa & pb) | (pa & carry) | (pb & carry); //得到进位标志位,只要有两个‘1’就进位
}
return arr + len; //arr申请字符串首地址,若len为0则有溢出数据,len为1则无数据溢出,我们申请空间的首位为空
}
仓促成文,不当之处,尚祈方家和读者批评指正。联系邮箱1772348223@qq.com