leetcode:67. 二进制求和

题目:

leetcode:67. 二进制求和_第1张图片

 

函数原型:

char * addBinary(char * a, char * b)

思路:

二进制相加,首先我们考虑先将字符串逆序。由此要写一个逆序函数reserve。字符串逆序后,从前往后相加,以较长的字符串的长度为标准长度n,另一未达标准长度字符串以 ‘0’ 补充(需要用辅助变量进行辅助相加,不可越界赋值为 ‘0’ )。创建新的字符串ans,申请空间为 n+2 个单位,初始化全部为 ‘0’ 。将两个字符串相加后的结果存入ans中,这里需要进行字符型数字与整型数字的转换。全部相加完成后,判断第 n+1 哥字符是否为 ‘0’ (初始时为 ‘0’),若仍为 ‘0’ 说明最后一位相加未进位,新字符串长度为 n+1 ,第 n+1 位赋值 ‘\0’,第n+2位也赋值为 ‘\0’;若不为 ‘0’ 说明最后一位相加进位了,第 n+1 位有值,将第 n+2 位赋值为 ‘\0’。最后再逆序新字符串ans(字符串逆序只会逆序 ‘\0’ 之前的字符),返回新字符串ans

 

关键1:为什么要将字符串逆序后再进行相加?

因为二进制相加可能会有进位问题,新字符串长度可能加1。如果不逆序,需要从后向前相加,前面留几个空间取决于相加后会不会进位,无法确定。相反,逆序后,从前向后相加,后面可以多留一个空间用于进位,如果没有进位该空间可置为 '\0' ,不影响字符串的再逆序。

 

关键2:为什么新的字符串要申请 n+2 个空间?

因为二进制相加后可能会进位,需要预留一个空间,再多申请一个空间用于存放 ‘\0’ 作为字符串结束标志。所以一共要多申请两个空间。

 

关键3:如何进行字符型数字于整型数字的转换?

字符型数字转整型数字:- ‘0’

整型数字转字符型数字:+ ‘0’

#include 
#include 
#include 
#include 

void reserve(char* arr)//逆序字符串
{
	int left = 0;
	int right = strlen(arr) - 1;
	while (left <= right)
	{
		char tmp = '0';
		tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;
		left++;
		right--;
	}
}

char* addBinary(char* a, char* b) 
{
	reserve(a);//逆序方便相加
	reserve(b);//逆序方便相加
	int sizea = strlen(a);//求长度
	int sizeb = strlen(b);//求长度
	int n = sizea > sizeb ? sizea : sizeb;//记下最大的长度
	char* ans = (char*)malloc(sizeof(char) * (n + 2));//创建最大长度+2的空间,因为可能要进位1个空间,还有一个空间用于存放\0
	memset(ans, '0', sizeof(char) * (n + 2));//全部初始化为0
	int i = 0;

	char aa = '0';//辅助变量
	char bb = '0';//辅助变量
	while (i < n)
	{
		if(i>=sizea||i>=sizeb)
		{
			if (i >= sizea)//判断相加时是否超出自己的长度,超出则补0处理
			{
				ans[i] = ans[i] - '0' + aa - '0' + b[i] - '0' + '0';
			}
			if (i >= sizeb)//判断相加时是否超出自己的长度,超出则补0处理
			{
				ans[i] = ans[i] - '0' + a[i] - '0' + bb - '0' + '0';
			}
		}
		else
		{
			ans[i] = ans[i] - '0' + a[i] - '0' + b[i] - '0' + '0';//新的字符串结果
		}
		
		if (ans[i] == '2')//进位判断(1+1的情况,前一位无进位)
		{
			ans[i] = '0';//当前位置为0
			ans[i + 1] = ans[i + 1] - '0' + 1 + '0';//进位操作
		}
		if (ans[i] == '3')//进位判断(1+1的情况,前一位进位1)
		{
			ans[i] = '1';//当前位置为1
			ans[i + 1] = ans[i + 1] - '0' + 1 + '0';//进位操作
		}
		i++;
	}
	//判断是否字符串长度增加(是否进位)
	if (ans[i] != '0')//进位了
	{
		ans[i + 1] = '\0';//最后一位置为\0
	}
	else//没有进位
	{
		ans[i] = '\0';//最后一位和倒数第二位都置为\0
		ans[i + 1] = '\0';
	}
	reserve(ans);//逆序昕字符串

	return ans;//返回新字符串
}

你可能感兴趣的:(leetcode刷题训练营,leetcode,算法,职场和发展)