상세 컨텐츠

본문 제목

[Go] Array and string - Add binary

Go/Leet Code

by Gopythor 2022. 4. 3. 20:15

본문

728x90
반응형

Given two binary strings a and b, return their sum as a binary string.

 

Example 1:

Input: a = "11", b = "1"
Output: "100"

Example 2:

Input: a = "1010", b = "1011"
Output: "10101"

 

Constraints:

  • 1 <= a.length, b.length <= 104
  • a and b consist only of '0' or '1' characters.
  • Each string does not contain leading zeros except for the zero itself.

 

My code

func addBinary(a string, b string) string {
	aa := strings.Split(a, "")
	bb := strings.Split(b, "")
	ans := make([]string, 0)
	alen := len(aa) - 1
	blen := len(bb) - 1
	carry := 0

	for alen >= 0 && blen >= 0 {
		switch {
		case carry == 1:
			if aa[alen] == "0" && bb[blen] == "0" {
				ans = append([]string{"1"}, ans...)
				carry = 0
				alen--
				blen--
			} else if aa[alen] == "1" && bb[blen] == "0" || aa[alen] == "0" && bb[blen] == "1" {
				ans = append([]string{"0"}, ans...)
				carry = 1
				alen--
				blen--
			} else {
				ans = append([]string{"1"}, ans...)
				carry = 1
				alen--
				blen--
			}
		default:
			if aa[alen] == "0" && bb[blen] == "0" {
				ans = append([]string{"0"}, ans...)
				carry = 0
				alen--
				blen--
			} else if aa[alen] == "1" && bb[blen] == "0" || aa[alen] == "0" && bb[blen] == "1" {
				ans = append([]string{"1"}, ans...)
				carry = 0
				alen--
				blen--
			} else {
				ans = append([]string{"0"}, ans...)
				carry = 1
				alen--
				blen--
			}
		}
	}

	if alen >= 0 {
		for alen >= 0 {
			switch {
			case carry == 1:
				if aa[alen] == "1" {
					ans = append([]string{"0"}, ans...)
					carry = 1
					alen--
				} else if aa[alen] == "0" {
					ans = append([]string{"1"}, ans...)
					carry = 0
					alen--
				}
			default:
				for i := alen; i >= 0; i-- {
					ans = append([]string{aa[i]}, ans...)
					alen--
				}
			}
		}
	} else if blen >= 0 {
		for blen >= 0 {
			switch {
			case carry == 1:
				if bb[blen] == "1" {
					ans = append([]string{"0"}, ans...)
					carry = 1
					blen--
				} else if bb[blen] == "0" {
					ans = append([]string{"1"}, ans...)
					carry = 0
					blen--
				}
			default:
				for i := blen; i >= 0; i-- {
					ans = append([]string{bb[i]}, ans...)
					blen--
				}
			}
		}
	}
	if carry == 1 {
		ans = append([]string{"1"}, ans...)
	}

	return strings.Join(ans, "")

}
  • I tried to keep binary numbers as string.
  • But i don't know why this code takes a lot of memories. I think becasue of prepend.
  • Strings will be allocated to array.
  • and ans slice will be made.
  • length of a and b will be allocated after minus one.
  • carry variable will store value when 1 will be handed to next number.
  • First for loop will run until alen or blen will be -1.
  • In for loop, there is a switch which checks carry is 1 or not.
  • If so, a value will be added to slice based on values of a and b.
  • carry will be changed also.
  • when a or b reches to -1, if condition waits for next step.
  • If alen is more than -1, then rest of them will be added to slice.
  • during this, carry still works.
  • When carry is still 1, 1 will be added to slice to the last of the code
  •  

sample 0 ms submission & sample 2300 KB submission

func addBinary(a string, b string) string {
    N := len(a)
    M := len(b)
    nR := max(M,N) + 1 
    r := make([]rune, nR)
    carry  := 0
    for i:=1 ; i < nR  ;i++ {
        left, right := 0, 0
        if N-i >=0  && a[N-i] == '1' {
            left = 1
        }
        if M-i >=0  && b[M-i] == '1' {
            right = 1
        }
        remain := (left+right+carry) % 2
        carry = (left + right + carry) / 2
        
        if remain == 0 {
            r[nR-i] = '0'
        } else {
            r[nR-i] = '1'
        }
    }
    if carry == 1 {
        r[0]  = '1'
        return string(r)
    }
    return string(r[1:])
}

func max( a, b int) int {
    if a > b {
        return a
    }
    return b
}
  • N and M will have values which are lengthes of a and b.
  • r slice which is rune will be made based on max length + 1 of longer one.
  • From for loop, End of array will be len -1 so it starts from 1.
  • Left and right valuables will have the number which has a and b array.
  • First and Second If condition checks it has 1 or not among array.
  • remain will have a value which is remainder after adding left and right and carry.
  • carry will have a value which is quotient after adding left and right and carry.
  • after this, remain value will be allocated to array.
  • Last of the code, if condition checks if carry is 1 or not. 
  • If so, 1 will be allocated to r[0].
  • or not it will be returned except r[0]
  • Rune is 4 bytes while string is 16 bytes.
  • good reference : https://thebook.io/006806/ch03/03/01_02/
  • https://darrengwon.tistory.com/1392
 

Go 언어 웹 프로그래밍 철저 입문: 3.3.1 문자열과 문자 - 2

 

thebook.io

 

 

 

sample 1 ms submission

func addBinary(a string, b string) string {
	c, _ := new(big.Int).SetString(a, 2)
	d, _ := new(big.Int).SetString(b, 2)
	return fmt.Sprintf("%b", new(big.Int).Add(c, d))
}
  • So simple Code. I think I should know this way also.
  • This code uses math/big package.
  •  If we use the big.Int and big.Rat types provided by the math/big package, you can use integers and rational numbers without a range limit. 
func (z *Int) SetString(s string, base int) (*Int, bool)
  • when we use octal then put 8 to base argument.
  • Add method will return int but Sprint convert int to String.

sample 2 ms submission

func addBinary(str1 string, str2 string) string {
    
    
    var zero byte = 48
	var one byte = 49
	if len(str2) > len(str1) {

		for len(str1) < len(str2) {
			str1 = "0" + str1
		}
	} else if len(str2) < len(str1) {
		for len(str2) < len(str1) {
			str2 = "0" + str2
		}
	}

	s3 := make([]byte, len(str1)+1)
	cf := false
	for i := len(str1) - 1; i >= 0; i-- {

		if str1[i] == one && str2[i] == one {
			if cf {
				s3[i+1] = one
			} else {
				s3[i+1] = zero
				cf = true
			}

		} else if str1[i] == one || str2[i] == one {
			if cf {
				s3[i+1] = zero

			} else {
				s3[i+1] = one

			}
		} else {
			if cf {
				s3[i+1] = one
				cf = false
			} else {
				s3[i+1] = zero
			}

		}

	}

	if cf {
		s3[0] = one
	} else {
		s3 = s3[1:]
	}

    return string(s3)
}

sample 2100 KB submission

func addBinary(a string, b string) string {
    i := len(a)-1
    j := len(b)-1
    carry := 0
    
    var res []byte
    for i >= 0 || j >= 0 || carry > 0 {
        sum := carry
        carry = 0
        if i >= 0 {
            if a[i] == '1' {
                sum++
            }
            i--
        }
        if j >= 0 {
            if b[j] == '1' {
                sum++
            }
            j--
        }
        switch sum {
        case 0:
            res = append(res, '0')
        case 1:
            res = append(res, '1')
        case 2:
            res = append(res, '0')
            carry = 1
        case 3:
            res = append(res, '1')
            carry = 1
        }
    }
    for i:=0;i<len(res)/2;i++ {
        j := len(res)-i-1
        res[i],res[j]=res[j],res[i]
    }
    
    return string(res)
}

sample 2200 KB submission

func addBinary(a string, b string) string {
    return reverse(add(reverse(a), reverse(b)))
}

func reverse(s string) string {
    bs := []byte(s)
    for i := 0; i < len(bs)/2; i++ {
        bs[i], bs[len(bs)-i-1] = bs[len(bs)-i-1], bs[i]
    }
    
    return string(bs)
}

func add(a string, b string) string {
    cin := byte(0)
    res := []byte{}
    i := 0
    j := 0
    for i < len(a) && j < len(b) {
        na := a[i]-'0'
        nb := b[j]-'0'
        s := na ^ nb ^ cin
        cin = (na & nb) | (na & cin) | (nb & cin)
        res = append(res, s+'0')
        i++
        j++
    }
    
    for i < len(a) {
        na := a[i]-'0'
        s := na ^ cin
        cin = na & cin
        res = append(res, s+'0')
        i++
    }
    
    for j < len(b) {
        nb := b[j]-'0'
        s := nb ^ cin
        cin = nb & cin
        res = append(res, s+'0')
        j++
    }
    
    if cin != 0 {
        res = append(res, cin+'0')
    }
    
    return string(res)
}

sample 2400 KB submission

func addBinary(a string, b string) string {
	lenA, lenB := len(a), len(b)
	if lenA > lenB {
		b = strings.Repeat("0", lenA-lenB) + b
	} else if lenB > lenA {
		a = strings.Repeat("0", lenB-lenA) + a
		lenA = lenB
	}
	isOne, res := false, make([]string, lenA)
	for i := lenA - 1; i >= 0; i-- {
		if a[i] == b[i] {
			res[i] = "0"
			if isOne {
				res[i] = "1"
			}
			isOne = a[i] == '1'
		} else if isOne {
			res[i] = "0"
		} else {
			res[i] = "1"
		}
	}
	if isOne {
		res = append([]string{"1"}, res...)
	}
	return strings.Join(res, "")
}

sample 2500 KB submission

func addBinary(a string, b string) string {
	lenA := len(a)
	lenB := len(b)

	i := lenA - 1
	j := lenB - 1

	var output string
	var sum int
	carry := 0
	for i >= 0 && j >= 0 {
		first := int(a[i] - '0')
		second := int(b[j] - '0')

		sum, carry = binarySum(first, second, carry)

		output = strconv.Itoa(sum) + output
		i = i - 1
		j = j - 1
	}

	for i >= 0 {
		first := int(a[i] - '0')

		sum, carry = binarySum(first, 0, carry)

		output = strconv.Itoa(sum) + output
		i = i - 1

	}

	for j >= 0 {
		second := int(b[j] - '0')

		sum, carry = binarySum(0, second, carry)

		output = strconv.Itoa(sum) + output
		j = j - 1
	}

	if carry > 0 {
		output = strconv.Itoa(1) + output
	}

	return output
}

func binarySum(a, b, carry int) (int, int) {
	output := a + b + carry

	if output == 0 {
		return 0, 0
	}

	if output == 1 {
		return 1, 0
	}

	if output == 2 {
		return 0, 1
	}

	if output == 3 {
		return 1, 1
	}

	return 0, 0
}

sample 2600 KB submission

func addBinary(a string, b string) string {
	lenA := len(a)
	lenB := len(b)

	i := lenA - 1
	j := lenB - 1

	var output string
	var sum int
	carry := 0
	for i >= 0 && j >= 0 {
		first := int(a[i] - '0')
		second := int(b[j] - '0')

		sum, carry = binarySum(first, second, carry)

		output = strconv.Itoa(sum) + output
		i = i - 1
		j = j - 1
	}

	for i >= 0 {
		first := int(a[i] - '0')

		sum, carry = binarySum(first, 0, carry)

		output = strconv.Itoa(sum) + output
		i = i - 1

	}

	for j >= 0 {
		second := int(b[j] - '0')

		sum, carry = binarySum(0, second, carry)

		output = strconv.Itoa(sum) + output
		j = j - 1
	}

	if carry > 0 {
		output = strconv.Itoa(1) + output
	}

	return output
}

func binarySum(a, b, carry int) (int, int) {
	output := a + b + carry

	if output == 0 {
		return 0, 0
	}

	if output == 1 {
		return 1, 0
	}

	if output == 2 {
		return 0, 1
	}

	if output == 3 {
		return 1, 1
	}

	return 0, 0
}
728x90
반응형

관련글 더보기

댓글 영역