注意题目要求中的“说明”部分:
- num1 和 num2 只包含数字 0-9。
- num1 和 num2 均不以零开头,除非是数字 0 本身。
解题基本思路直截了当,就死模拟乘法过程。
假设两字符串是,“12345”和“678”,
先计算 “12345”乘以“600”,
再计算 “12345”乘以“70”,加上前一步的中间结果,
然后是 “12345”乘以“8”,加上前一步的中间结果。
得到最终结果。
代码已提交通过。
func multiply(num1 string, num2 string) string {
// 空串无意义
if num1 == "" {
panic("num1 is empty")
}
if num2 == "" {
panic("num2 is empty")
}
if num1 == "0" || num2 == "0" { // 只要有一个数是0,结果就是0
return "0"
}
// 如果一个数是1,结果就是另外一个数
if num1 == "1" {
return num2
}
if num2 == "1" {
return num1
}
// 选出长度较短的,便于后续优化
if len(num1) <= len(num2) {
return multiplyImpl(num1, num2)
}
return multiplyImpl(num2, num1)
}
func multiplyImpl(sn, ln string) string {
var(
sl = len(sn)
ll = len(ln)
// res和tmp在下面循环过程中可以复用
res = make([]byte, 1, ll)
tmp = make([]byte, 0, ll)
)
res[0] = '0'
for i := 0; i < sl; i++ {
tmp = mul(ln, sn[i], sl-i-1, tmp[:0])
res = add(res, tmp)
}
// 翻转res中的元素使得左边是高位,右边是低位。
for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
res[i], res[j] = res[j], res[i]
}
return string(res)
}
// 注意这里的结算结果在[]byte中的放置顺序,左边是低位,右边是高位。
// 比如某个中间结果的整数形式是 123450,
// 在[]byte中的放置情况是 ['0','5','4','3','2','1']。
func mul(m string, s byte, suffixZeroCount int, tmp []byte) []byte {
if s == '0' {
return append(tmp, '0')
}
for i := 0; i < suffixZeroCount; i++ {
tmp = append(tmp, '0')
}
if s == '1' { // 可以简化处理
for i := len(m)-1; i >= 0; i-- {
tmp = append(tmp, m[i])
}
return tmp
}
var(
r int
sn = getN(s)
)
for i := len(m)-1; i >= 0; i-- {
x := sn*getN(m[i]) + r
tmp = append(tmp, getB(x%10))
r = x/10
}
if r > 0 {
tmp = append(tmp, getB(r))
}
return tmp
}
// 输入的两个[]byte中的放置顺序都是左边是低位,右边是高位。
func add(res, b []byte) []byte {
bl := len(b)
if bl == 1 && b[0] == '0' {
return res
}
var (
i int
j int
r int
al = len(res)
)
for i < al && j < bl {
x := getN(res[i])+getN(b[j]) + r
d := getB(x%10)
if i < len(res) {
res[i] = d
} else {
res = append(res, d)
}
r = x/10
i++
j++
}
var iEnd bool
for i < al { // 处理剩余部分
x := getN(res[i]) + r
d := getB(x%10)
if i < len(res) {
res[i] = d
} else {
res = append(res, d)
}
r = x/10
i++
iEnd = true
}
for j < bl { // 处理剩余部分
x := getN(b[j]) + r
d := getB(x%10)
if j < len(res) {
res[j] = d
} else {
res = append(res, d)
}
r = x/10
j++
}
if r > 0 { // 如果还有进位
d := getB(r)
if iEnd {
if i < len(res) {
res[j] = d
} else {
res = append(res, d)
}
} else {
if j < len(res) {
res[j] = d
} else {
res = append(res, d)
}
}
}
return res
}
// 将字符形式的数字转换成整型
func getN(b byte) int {
return int(b-'0')
}
// 将整型数字转换成字符形式
func getB(n int) byte {
return byte(n)+'0'
}