给你两个二进制字符串 a
和 b
,以二进制字符串的形式返回它们的和。
示例 1:
输入:a = "11", b = "1" 输出:"100"
示例 2:
输入:a = "1010", b = "1011" 输出:"10101"
提示:
1 <= a.length, b.length <= 104
a
和b
仅由字符'0'
或'1'
组成- 字符串如果不是
"0"
,就不含前导零
难点分析:
1.a和b数组都是char类型数组,要计算需先将数据转化为int类型,并在最后再转化为char类型数组
2.a数组和b数组长度不一,且都是逆序,这意味着逐项相加再项高位进位将很麻烦
3.新生成的数组长度的如何确定
思路:
先从两个数组的最高位向最低位逆序遍历,将相对应的数据相加。这里使用calloc数组可以在分配空间后自动将其初始化为0;出于谨慎性,分配的空间大小置为maxLength+2,考虑到了可能的进位信息和终止符(注意,这里只是分配空间,并不一定要去使用!)。而使用k作为遍历索引来存放两个数组相应位的加总信息。这里由于判断条件,加总结束后得到的新数组的遍历索引k可能等于1(不存在进位信息)也可能等于0(不存在进位信息),随后继续使用k作为索引,将加总得到的sumDigits数组复制到最终的答案result数组,注意用于result仍使用k作为索引,且循环条件为 for (int l = k + 1; l < maxLength + 2; l++),这就根据加总后k的值自动确定了答案数组的长度(即是否存在进位信息)。最后释放内存空间。
char* addBinary(char* a, char* b) {
if (strcmp(a, "0") == 0) return b; //字符串的比较要使用strcmp函数
if (strcmp(b, "0") == 0) return a;
int len1 = strlen(a);
int len2 = strlen(b);
int maxLength = (len1 > len2) ? len1 : len2; //得到数组长度较长者
int* sumDigits = (int*)calloc(maxLength + 2, sizeof(int)); // 多分配一个位置用于进位和终止符
//这里是出于谨慎性考虑多分配了两个位置,实际上可能不需要考虑进位信息.
//这里只是分配了空间,并不一定会去使用它们
int carry = 0; //进位信息
int i = len1 - 1, j = len2 - 1, k = maxLength + 1; // 从后往前遍历,k指向sumDigits的末尾
while (i >= 0 || j >= 0 || carry) {
int digitA = (i >= 0) ? a[i--] - '0' : 0; //别忘记a和b是char类型,用于计算需要先减去'0'
int digitB = (j >= 0) ? b[j--] - '0' : 0;
int sum = digitA + digitB + carry; //计算两个数组相对应的每一位的加总
sumDigits[k--] = sum % 2; //取余处理
carry = sum / 2; //除处理,获取余数,即进位信息
}
// 将sumDigits转换为字符串
char* result = (char*)calloc(maxLength + 2, sizeof(char)); // 多分配一个位置用于终止符
//这里遍历条件l=k+1,而k是上面用于计算加总求和的,因此k最后的值可能等于0也可能等于1(取决于最高位是否有进位)
//这样就解决了a和b数组相加后可能产生的进位问题
for (int l = k + 1; l < maxLength + 2; l++)
{
result[l - k - 1] = sumDigits[l] + '0'; //别忘记要返回的是char数组,因此要+'0'
}
free(sumDigits); // 释放中间结果的内存
return result;
}
笔记
1.字符串不能使用“==”来比较,应使用strcmp
函数来比较两个字符串。
关于strcmp函数:
函数原型:int strcmp(const char* str1, const char* str2)
作用:比较字符串str1和str2是否内容一致
头 文 件:#include <string.h>
返 回 值:str1 = str2 则返回0,
str1 > str2 则返回大于0的值,
str1 < str2 则返回小于0的值
说明:字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。strcmp()首先将s1 第一个字符值减去s2 第一个字符值,若差值为0 则再继续比较下个字符,若差值不为0 则将差值返回。但是并不是所有系统都返回差值,有的系统只返回0,1和-1三个值。
2.calloc函数在分配内存空间的同时,能为所分配得到的内存空间初始化为0。
注意:calloc与malloc相似,除了会初始化分配的空间。关于calloc函数:
calloc(size_t num, size_t size);
参数:
num
:要分配的元素数量(即数组的大小)。size
:每个元素的大小(以字节为单位)。
返回值:
- 如果成功,
calloc
返回一个指向已分配内存的指针。 - 如果失败,
calloc
返回NULL
。
calloc
与 malloc
的主要区别在于:
- 内存初始化:
calloc
会将分配的内存初始化为零,而malloc
则不会。这意味着,如果你需要一个包含零的数组或数据结构,使用calloc
是更安全的,因为它会确保所有的位都被设置为零。 - 计算总大小:
calloc
允许你指定元素数量和每个元素的大小,然后它会自动计算总的大小(num * size
)。而malloc
需要你直接指定总的大小。