LLeetcode. 67.二进制求和

1.题目描述:

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

示例1:

输入:a = “11”, b = “1”
输出:“100”

示例2:

输入:a = “1010”, b = “1011”
输出:“10101”

提示:

  1. 1 <= a.length, b.length <= 104
  2. a 和 b 仅由字符 ‘0’ 或 ‘1’ 组成
  3. 字符串如果不是 “0” ,就不含前导零

2.解题思路

  1. 直接解法,可以将数直接转换为10进制数进行加减,然后再将结果转换为二进制数输出。(本次不介绍此种方法);
  2. 模拟进位,即每碰见二则向前进一位。

让我们先想想10进制我们是怎样求解两个数的合的:

  1. 从个位开始,个位与个位相加,然后判断是否进1,若结果大于10,用该结果除以10,商 (a+b)/10 为进位,余数(a+b)%10为结果保留在个位。然后前一位计算结果的商为(a+b+进位)/10余数为(a+b+进位)%10。我们得到了解题规律。

  2. 二进制的计算无外乎将10替换为2;商为(a+b+进位)/2表示结果余数为(a+b+进位)%2表示进位

  3. 为了方便计算,我们可以先将字符串反向,然后开始遍历计算结果,最后将结果反向输出;

3.c语言代码描述

#include
#include
#include//包含malloc动态申请函数
char * addBinary(char * a, char * b);
char * revise(char *a);
int main()
{
	char a[5]={"1010"};
	char b[5]={"1011"};
	char *c=addBinary(a,b);
	printf("%s",c);
	return 0;
}
char * revise(char *a)
{
	int x=strlen(a);
	int i=0;
	char temp;
	for(i=0;i<(x/2);i++)//循环到中间的数,将两头交换,注意数组不能越界
	{
		temp=a[i];
		a[i]=a[x-i-1];
		a[x-i-1]=temp;
	}
	return a;
}
char* addBinary(char * a, char * b)
{
	int len_a=strlen(a),len_b=strlen(b);
	int max= len_a > len_b ? len_a:len_b;
	int min= len_a < len_b ? len_a:len_b;//取两个字符串的最大与最小值
	revise(a);
	revise(b);
	int carry=0,i=0;//进位初始为0;
    char *c=(char*)malloc(sizeof(char)*(max+1));
	for(i=0;i<max;i++)
	{
		if(i<min)//当两个字符串都有数字时,两者相加
		{
			if((carry+(b[i]-'0')+(a[i]-'0'))%2==0)
			 c[i]='0';
			else
			 c[i]='1';//c只有1或0,所以当结果为0,输出字符串‘0’
			carry=(carry+(b[i]-'0')+(a[i]-'0'))/2;
		}
	    else//相反,较小的字符串结果为0;
	    {
	    	if(len_a==min)
	    	{
	    	    if((carry+(b[i]-'0'))%2==0)
			      c[i]='0';
			    else
			      c[i]='1';
	    			carry=(carry+(b[i]-'0'))/2;
			
			}
			else
			{
	    		if((carry+(a[i]-'0'))%2==0)
			      c[i]='0';
			       else
			     c[i]='1';
	    		carry=(carry+(a[i]-'0'))/2;
			}
		}
	}
    if(carry!=0)//末尾处理,如果进位不为0,则向前进一;
     {c[max]='1';
    c[max+1]='\0';//字符串结尾处理,根据长度结束字符串;
    }
    else
    {
      c[max]='\0';
    }
    revise(c);
	return(c);
}

4.易犯错误:

  1. char *c=(char*)malloc(sizeof(char)*(max+2)); 注意申请内存的格式并且注意大小应该为max+2;max+1是两个字符串相加的大小不会超过max+1,但是由于字符串还要有一个区域储存(‘\0’)作为结束,所以其大小为max+2;
  2. 注意strlen返回的长度不算’\0’而sizeof()返回的长度计算了’\0’;
  3. malloc申请的内存在堆区域之中,但是若是在函数中定义一个数组c[max+2]其内存保存在栈区,在调用之后会被清除,所以不能定义局部变量c[max+2]保存然后返回c,而应该用malloc函数申请动态数组。

你可能感兴趣的:(Leetcode,简单题刷题,算法,开发语言,c语言,leetcode,数据结构)