二进制求和 : 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。

例1:输入参数("11","1"),返回"100";

例2:输入("1010","1011"),返回"10101"

        首先我们来看一下二进制加法,类似于十进制加法。十进制加法在列竖式上是按最低位数将位数对齐后,从右往左加,逢十进一。那么二进制加法就是位数对齐,从右往左加,逢二进一。

这里要用到动态内存,因为有进位问题,随时可能都要多一个格子。

两个数相加,和的位数长度最长可能为两个数的长度中最长的长度位数加一。

通常两个相加的字符串a和b前面会加const,因为两个数相加那么这两个数的值也不能改变。

因为加法是从右往左加,所以下标要从后往前遍历。两个加数的下标(i,j)可以从后往前遍历(i,j--),但和的下标(k)只能从前往后遍历(k++),因为和的具体长度是不能确定的。所以这个相加的结果是一个反的字符串,那么最后在将这个字符串反转一次就是我们要求的真正的和。

我们还需要单独定义一个变量,来保存进位。再说到逢二进一,就是相加为2的结果会变成0,这里用到的就是对2取余。例如十进制中的6+7为13中的个位为3就是 13对10取余剩下的3.而在二进制中1+1为2那么2对2取余,余数就是个位的0.

而进位的1是2除2为1,例如13除10为1.

这里相同位数相加后,此位数的值是相加结果对进制数(如2,10)取余得到的。而进位数的值是相加结果除进制数得到的。

char* AddBinary(const char* str1, const char* str2)
{
	int len1 = strlen(str1);//用strlen函数专门求字符串的长度
	int len2 = strlen(str2);
	int len = (len1 < len2 ? len1 : len2)+1;//str的长度,和的长度最多比较长的字符串多一个(即那个进位的)字符
	//char* str = (char*)malloc(len * sizeof(char));//是错的,字符串里有结尾'\0'的问题
	char* str = (char*)malloc((len +2)* sizeof(char));
	int sum = 0;//和
	int flg = 0;//进位值
	int i;//str1从后往前的下标
	int j;//str2从后往前的下标
	int k=0;//str的下标
	//从后往前遍历且两个字符串都还有数据需要按位相加
	for (i = len1 - 1, j = len2 - 1; i>=0&&j>=0; i--, j--)
	{
		//sum = str1[i] + str2[j];//这是错的,因为这是字符1加字符0,而我们要的是数字1加数字0
		//将字符1转为数字1即用字符1减去字符0就是数字1:"1"-"0"->1.同理:1+"0"->"1"
		sum =( str1[i]-'0' )+ (str2[j]-'0')+flg;//第一次加0
		str[k++] = (sum % 2)+'0';//数字转字符,加完k往后走
		flg = sum / 2;
	}
	//只剩一个字符串有数据,另一个已经完了。归并算法也类似,一个长,一个短。要有两个循环但只有一个会被执行到
	while (i >= 0)
	{
		sum = str[1] - '0' + flg;
		str[k++] = (sum % 2) + '0';
		flg = sum / 2;
		i--;
	}
	while (j>= 0)
	{
		sum = str[2] - '0' + flg;
		str[k++] = (sum % 2) + '0';
		flg = sum / 2;
		j--;
	}
	if (flg != 0)//最左边还有一个进位的数字
	{
		str[k++] = '1';
		//str[k++] = flg + '0';//等同于str[k++]=1
		str[k] = '\0';//把str处理为字符串

		//字符串反转
		char tmp;
		for (i = 0, --k; i < k; i++, k--)//i,k交换数据
		{
			tmp = str[i];
			str[i] = str[k];
			str[k] = tmp;

		}
		
	}
	return str;//返回字符串
}
int main()
{
	const char* str1 = "1010";
	const char* str2= "1011";
	char* p = AddBinary(str1, str2);
	printf("%s\n", p);//%s输出字符串
	free(p);
	return 0;
}

//例2:输入("1010", "1011"), 返回"10101"

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值