-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultiply_strings.go
86 lines (72 loc) · 1.38 KB
/
multiply_strings.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// https://leetcode.com/problems/multiply-strings/
package multiply_strings
func multiply(num1 string, num2 string) string {
if len(num1) == 0 || len(num2) == 0 {
return ""
}
n1 := len(num1)
n2 := len(num2)
products := make([][]byte, n2)
shift := 0
for i := n2 - 1; i >= 0; i-- {
products[i] = mulSingle(toBytes(num1), num2[i]-'0', n2+n1, shift)
shift++
}
return toChars(add(products, n2+n1))
}
func toBytes(s string) []byte {
n := []byte(s)
for i, v := range n {
n[i] = v - '0'
}
return n
}
func toChars(n []byte) string {
for i, v := range n {
n[i] = v + '0'
}
return string(n)
}
func add(nums [][]byte, size int) []byte {
carry := int(0)
res := make([]byte, size+1)
rIdx := size
for i := size - 1; i >= 0; i-- {
s := carry
for j := range nums {
s = s + int(nums[j][i])
}
carry = s / 10
v := byte(s % 10)
res[rIdx] = v
rIdx--
}
for ; carry != 0; carry /= 10 {
res[rIdx] = byte(carry % 10)
rIdx--
}
return trimLeft(res)
}
func trimLeft(r []byte) []byte {
i := 0
for ; i < len(r)-1 && r[i] == 0; i++ {
}
return r[i:]
}
func mulSingle(num1 []byte, a byte, size, shift int) []byte {
carry := byte(0)
rIdx := size - shift - 1
res := make([]byte, size)
for i := len(num1) - 1; i >= 0; i-- {
b := num1[i]
pd := a*b + carry
carry = pd / 10
res[rIdx] = pd % 10
rIdx--
}
if carry != 0 {
res[rIdx] = carry
rIdx--
}
return res
}