给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1
和 0
。
这个代码是抄网友的,觉得他写得好巧妙。
因为有可能出现进位,所以重新开辟内存len+1,而还要放"\0",所以len+2。注意的是因为数组是从0开始,结束符在数组的位置是len+1。
模拟加法部分:carry可以理解为进位,因为两个字符串只要还有数都要继续加,而如果两个字符串的数都加完有进位时,需要将进位(carry)的值加到最前面。
所以条件为(i >= 0 || j >= 0 || carry > 0)。
而三目运算符需要将carry +=和(i >= 0) ? a[i--] - '0' : 0 分开看。先看右边如果条件i >= 0成立则运算a[i--] - '0',因为字符串里的是字符,通过运算后会变成整形值用于运算。所以他先把a和b同位的值相加放到carry中,通过carry % 2 + '0'; carry /= 2;语句实现如果没进位和有进位的情况。
最后:return res+k+1 ; //因为预留多一位用来最高位进位,若没有进位res[0]就没有值则不能直接返回res,而是返回第二个元素地址,修改为res+1,但有进位时又要返回首元素地址,则应该改为res+k+1
char * addBinary(char * a, char * b){
int carry = 0;
int lena = strlen(a);
int lenb = strlen(b);
int len = fmax(lena, lenb);
int i = lena - 1;
int j = lenb - 1;
char *res = (char*)malloc(sizeof(char) * (len + 2)); /* 长度可能是更长的字符串加1 */
int k = len + 1;
res[k--] = '\0'; /* 添加结束符 */
/* 模拟加法处理 */
while (i >= 0 || j >= 0 || carry > 0) {
carry += (i >= 0) ? a[i--] - '0' : 0;
carry += (j >= 0) ? b[j--] - '0' : 0;
res[k--] = carry % 2 + '0';
carry /= 2;
}
return res+k+1 ; //因为预留多一位用来最高位进位,若没有进位res[0]就没有值则不能直接返回res,而是返回第二个元素地址,修改为res+1,但有进位时又要返回首元素地址,则应该改为res+k+1
}