import Foundation
/*
43. Multiply Strings
Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2.
Note:
The length of both num1 and num2 is < 110.
Both num1 and num2 contains only digits 0-9.
Both num1 and num2 does not contain any leading zero.
You must not use any built-in BigInteger library or convert the inputs to integer directly.
*/
/*
Thinking:
需要模擬單個位上的乘法,主要要儲存進位和余數(shù)
例如 18 * 8
-------
18
8
64 --> 個位 (6, 4) //進6, 余4 a(個位)*b(個位)
8 -> 十位 8+6 (1,4) //進1,余4,a(十位) * b(個位) a(個位) * b(十位)
我們從個位開始計算,每次計算的結(jié)果丟入到一個棧結(jié)構(gòu)中,
例如 18 * 12
例如首先計算18* 2, 先是8*2,產(chǎn)生了1的進位,6的余數(shù),6進入棧,1記錄
然后1*2, 2+之前的進位,產(chǎn)生3, 0的進位,3的余數(shù),3進入棧,一次循環(huán)結(jié)束。
第二次循環(huán),從棧的index = 1 開始,注意這里計算位置要反向計算
18*1 , 先是8*1,產(chǎn)生0的進位,8的余數(shù),8丟進棧的1位置,1有值,則為3+8 = 11,
1 放入棧,產(chǎn)生了1 的進位,放到當前存儲進位的位置
然后1*1, 產(chǎn)生了0的進位,1的余數(shù),加上進位,就變成2, 放入到棧中。
單個過程就是:
計算->存儲進位->pushStack->返回進位->合并存儲進位
下一次
//Error: 如果要頻繁的遍歷字符,也許轉(zhuǎn)換為C字符串更高效。
*/
func multiply(_ num1: String, _ num2: String) -> String {
let length1 = num1.lengthOfBytes(using: .ascii)
let length2 = num2.lengthOfBytes(using: .ascii)
guard length1 > 0, length2 > 0 else {
return ""
}
var calcResultStack: [Int] = [Int]() //存儲結(jié)構(gòu)
var bit: Int = 0 //存儲進位
//計算是從個位開始,所以是反向計算
print("0000+ \(CFAbsoluteTimeGetCurrent())")
let num1Scalar = num1.cString(using: .ascii)
let num2Scalar = num2.cString(using: .ascii)
print("1111+ \(CFAbsoluteTimeGetCurrent())")
//把計算結(jié)果push到 stack 結(jié)構(gòu)中去,然后返回結(jié)果產(chǎn)生的進位
func push(_ left: Int, _ index: Int) -> Int {
var appendValue = left //應該合并進的數(shù)
var bitValue = 0 //產(chǎn)生的進位
if calcResultStack.count > index {
appendValue += calcResultStack[index]
calcResultStack[index] = appendValue % 10
bitValue = appendValue / 10
} else {
//Error: 不能直接存進去,因為也可能超過10
calcResultStack.append(appendValue % 10)
bitValue = appendValue / 10
}
return bitValue
}
//根據(jù)輸入值,計算出進位,返回(應該入棧的結(jié)果,進位)
let zeroValue = ("0" as UnicodeScalar).value //獲取0的 unicode值
func calc(_ left: Int, _ right: Int) -> (Int, Int) {
let l = left - Int(zeroValue)
let r = right - Int(zeroValue)
let value = l * r
return (Int(value % 10), Int(value / 10))
}
print("2222+ \(CFAbsoluteTimeGetCurrent())")
for i in stride(from: length1 - 1, through: 0, by: -1) {
let v = Int(num1Scalar![i])
for i2 in stride(from: length2 - 1, through: 0, by: -1) {
let v2 = Int(num2Scalar![i2])
var (result, add) = calc(v, v2) //add 是下一次計算需要的進位
result += bit //先加上之前的進位
let pushAdd = push(result, length1 - 1 - i + length2 - 1 - i2) //計算出入棧產(chǎn)生的下一次進位
bit = add + pushAdd
}
if (bit != 0) {
//一次內(nèi)循環(huán)結(jié)束,如果還有進位,則需要進位
calcResultStack.append(bit)
bit = 0
}
}
print("3333+ \(CFAbsoluteTimeGetCurrent())")
let reversedStack = calcResultStack.map {
String($0)
}.reversed()
var retString: String = ""
var start = false
for value in reversedStack {
if value != "0", !start {
start = true
}
if start {
retString.append(value)
}
}
if retString.isEmpty {
retString = "0"
}
return retString
}
print(multiply("7", "871"))
43. Multiply Strings
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 問題描述 Given two non-negative integers num1 and num2 repres...
- 題目: 給定兩個字符串十進制數(shù)字,給出字符串為他們的乘積。要求如下: 禁止使用內(nèi)置大數(shù)算法。 字符串長度110 輸...
- 原題鏈接:Multiply Strings 忽然發(fā)現(xiàn)用Python做面試題簡直就像開了掛一樣。。。太強大了!代碼如下:
- Given two non-negative integers num1 and num2 represented...