Binary Sum, Detailed Analysis + Two Ideas + Summary of Knowledge Points

Keywords: C C++ leetcode

Binary Sum

🔥🔥A special column was opened to record LeedCode topics, summarize ideas, analyze topics, summarize knowledge points, practice makes perfect! Welcome to collection!

1. Title

Give you two binary strings and return their sum (in binary).

The input is a non-empty string and contains only the numbers 1 and 0.

  • Example 1:
input: a = "11", b = "1"
output: "100"
  • Example 2:
input: a = "1010", b = "1011"
output: "10101"

Tips:

  • Each string consists of only the characters'0'or'1'
  • 1 <= a.length, b.length <= 10^4
  • String does not contain leading zeros if it is not "0"
char * addBinary(char * a, char * b){
    

}

2. Solving problems

1.Simulated implementation meets binary

Since you have only just finished learning c, write down only the version of C, and then update it when you finish learning C++ or java.

Hard, the idea is correct, but it doesn't work. You guys who have reference questions write it out at the end. As a result, the vegetable is ready to be refreshed.

Let's analyze step by step:

If you can keep up with my thoughts, keep looking!!

☁️Analysis Title: Get the title, browse through it, I think everyone is very direct, want to add the two strings of numbers directly, and then get the number, in binary format, but how to achieve it needs many steps backward

☁️Analysis interface: A and b are two strings, and the return value is a string, which is our carry-through string

Here, in my opinion, there are three difficulties:

  • 🌊Because numbers are inside strings, this allows strings to be converted to numbers and numbers to be converted to strings.
  • 🌊A string is required to store the number, and the length of the string is determined by the longest one in a and b
  • 🌊How the resulting number is carried in binary form

Next, analyze each one:

Let's start with the second question, because it needs to create variables first

We need:

  1. ☀️The length of the longest string in a and b, where a trinomial operator is used or not used

  2. ☀️We need string space that can hold the size of the binary digits that follow

    Think about things like:

    🌀Situation 1

    input: a = "11", `b = "11"
    output: "110"
    //After the "22" binary form is rounded in, it becomes 110, so the longest is the + 1 in a and b
    

    🌀Situation 2

    input: a = "100", b = "11"
    output: "111"
    //"111" This is no carry case
    

Since the size of a string changes with the size of len, we need to open up space to store the string because the length of the character array is fixed and cannot have variables, so we can only dynamically open up memory space

char * addBinary(char * a, char * b){
    int len1 = strlen(a);//Length of a
    int len2 = strlen(b);//Length of b
    int len = (len1 > len2) ? (len1) : (len2);
    //Here len is the longest one in ab
    char* ret = (char*)malloc(sizeof(char) * (len + 2));
    //Create dynamic memory space, most likely len+1, because'\0'follows
    //So the last one is len+2
    
}

We got an array to hold the last string

Next we ask for the last string

char * addBinary(char * a, char * b){
    int len1 = strlen(a);//Length of a
    int len2 = strlen(b);//Length of b
    int len = (len1 > len2) ? (len1) : (len2);
    //Here len is the longest one in ab
    char* ret = (char*)malloc(sizeof(char) * (len + 2));
    //Create dynamic memory space, most likely len+1, because'\0'follows
    //So the last one is len+2
    int remain = 0;//Store digits corresponding to the addition of bits
    //If it is 2, what is the bit after remaining%2 equals rounding
    //How many rounds does remain get by dividing 2
    int i = len1 - 1;//Length of a
    int j = len2 - 1;//Length of b
    //We need it to locate the numbers that need to be added
    int k = len + 1;
    //The last position of the last string array because we are counting backwards
    ret[k--] = '\0';
    //Assign the end symbol, and by the way point the value of k to the last character in the array, not'\0'
}

Next comes calculation, analysis of 1 and 3 difficulties

This is a loop, and the loop ends when the corresponding characters a and b have been calculated

If you encounter an end-first, the remaining corresponding bit is assigned directly to the last string

while (i >= 0 || j >= 0 || remain > 0)
// 111  111
// 222 -> I = 3, J = 3, after
//remain or 1, need to add remaim to next
{
    //Character to number: Character -'0'=corresponding number
    remain += (i >= 0) ? a[i--] - '0' : 0;
    //A Before the end, save a number from right to left in order to remain
    //Do not add value to remain after end of a
    remain += (j >= 0) ? b[j--] - '0' : 0;
    //b Before the end, save a number from right to left in order to remain
    //b After end, do not add value to remain
    ret[k--] = remain % 2 + '0';
    //Convert the modeled value to a character, assign ret[k], and by the way, position K next (left)
    remain /= 2;//Add a few to the next digit after rounding
}

return ret + k + 1;
//At the end ret is the array name, + (k + 1) is to see where the first character is
//Consider that because K was last ret[0],k--followed by -1, you need to + 1

The final code is:

char * addBinary(char * a, char * b){
    int len1 = strlen(a);
    int len2 = strlen(b);
    int len = (len1 > len2) ? (len1) : (len2);
    char* ret = (char*)malloc(sizeof(char) * (len + 2));
    if(ret == NULL)
    {
        exit(-1);//To prevent malloc from failing
    }
    int remain = 0;
    int i = len1 - 1;
    int j = len2 - 1;
    int k = len + 1;
    ret[k--] = '\0';
    while (i >= 0 || j >= 0 || remain > 0)
    {
        remain += (i >= 0) ? a[i--] - '0' : 0;
        remain += (j >= 0) ? b[j--] - '0' : 0;
        ret[k--] = remain % 2 + '0';
        remain /= 2;
    }
    return ret + k + 1;
}

2.Bit operation

It's not entirely fantastic either, but you must be very skilled at using bitwise operators to come up with this approach

According to official summary

We can design such an algorithm to calculate:

while(remian)
{
    nums = a ^ b;
    //Adds a and b, the current carry, but adds 1 to the next without adding
    //No carry addition for short, but carry anyway
    remain = (a & b) << 1;
    //Keep the digits that need to be rounded here, but the digits are still in their current position
    //We need to move one bit to the left so that additions count as rounds
    a = nums;
    b = remain;
}

In the first round of calculation, the last answer is the result of the addition of a and B.The second-to-last digit of a and B is the additive digit of the last digit of a and B. In each subsequent round, since carry is obtained by bitwise and left-shifting of a and b, then zero is added at the end, so the following digits are not affected in the following calculation. Each round can get a low I-bit answer and its position to the lower i+1 digit, thus simulating the addition process.

It's a good idea, but no one seems to be able to do it this way (because it will overflow), so if someone writes it, they can share it!

But ideas can be learned
The main thing is to get the number after adding up, and finally to achieve the same as the first kind, change soup without changing medicine

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>


int rev(char* n)
{
    int num = 0;
    while (isdigit(*n))//judge
    {
        num = num * 10 + (*n - '0');
        n++;
    }
    return num;
}

char* addBinary(char* a, char* b)
{
    int len = strlen(a) > strlen(b) ? strlen(a) : strlen(b);
    int carry = 1;
    int a1 = rev(a);
    int b1 = rev(b);
    int answer = 0;

    while (carry)
    {
        answer = a1 ^ b1;
        carry = (a1 & b1) << 1;
        a1 = answer;
        b1 = carry;
    }
    int k = len + 1;
    char* ret = (char*)malloc(sizeof(char) * (len + 2));
    if (ret != NULL)
    {
        ret[k--] = '\0';
        //k is len after end
    }
    else
    {
        exit (-1);
    }
    if (answer == 0)
    {
        return "0";
    }

    while (answer)
    {

        ret[k--] = (answer % 2 + '0');//This is done in binary form
        if (answer % 10 >= 2)
        {
            answer = answer / 10 + 1;
        }
        else
        {
            answer = answer / 10;
        }
                                                                           

    }

    return ret + k + 1;
}


int main()
{
    char* x = "101";
    char* y = "1";

    printf("%s", addBinary(x, y));
    
    return 0;

}

3. Summary

Knowledge Points:

  • ⛄How to calculate the conversion between integer numbers and their binary form
  • ⛄How to calculate the conversion between a number string and an integer number
  • ⛄Array space is determined by a variable and can be exploited using dynamic memory
  • ⛄_Bitwise XOR of two numbers yields a number that is the original number without carry addition
  • ⛄_Two numbers bitwise and, resulting in a number that moves one unit to the left, is the number that adds up requires corresponding bitwise digits

Posted by awais_ciit on Thu, 14 Oct 2021 10:28:57 -0700