LeetCode-中等-43-字串相乘-迭代(C)
阿新 • • 發佈:2021-02-15
文章首發及後續更新:https://mwhls.top/1657.html
新的更新內容請到mwhls.top檢視。
無圖/無目錄/格式錯誤/更多相關請到上方的文章首發頁面檢視。
題目
給定兩個以字串形式表示的非負整數num1和num2,返回num1和num2的乘積,它們的乘積也表示為字串形式。
示例 1:
輸入: num1 = "2", num2 = "3"
輸出: "6"
示例2:
輸入: num1 = "123", num2 = "456"
輸出: "56088"
num1和num2的長度小於110。
num1 和num2 只包含數字0-9。
num1 和num2均不以零開頭,除非是數字 0 本身。
不能使用任何標準庫的大數型別(比如 BigInteger)或直接將輸入轉換為整數來處理。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/multiply-strings
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
思路
- 這道題的思路就如同日常解乘法題一樣,num1的每位數字*num2*權值,再把他們加起來即可。
- 所以這裡講一下程式碼中處理的一些東西:
- 首先是進位carry,用迭代的方式處理:
- 如果是在每次計算後就將進位加上去,那麼還會影響更高位的數,更高位的數也可能進位,可能會一直進位到最高位,實現起來很麻煩。
- 因此將進位作為一個結果,用於下一輪的計算,像是迭代一樣。
- 然後是當前計算的位置current:
- 用tempProduct儲存當前位置的乘積結果,tempProduct的十位是carry,作為下一次的進位,個位是current,作為本次乘積的新結果。
- current在乘積計算前,表示的是當前位置的數字,計算後也是,但會變化。
- 用tempProduct儲存當前位置的乘積結果,tempProduct的十位是carry,作為下一次的進位,個位是current,作為本次乘積的新結果。
- 以及積的長度:
- n位數*n位數,如果乘數沒有0,那麼長度是2n-1或2n。
- 9*9=81,1*1=1。
- 因此直接分配2n+1個位置即可。
- 為了計算時方便判斷當前位的值,將所有的位置都初始化成'\0'。
- n位數*n位數,如果乘數沒有0,那麼長度是2n-1或2n。
- 在計算上:
- 為了方便計算,個位是product[0],十位是product[1],即倒序。
- 所以計算結束後要將其轉成正序。
- 首先是進位carry,用迭代的方式處理:
程式碼
char * multiply(char * num1, char * num2){
int len1, len2, pos1, pos2, current, carry, tempProduct;
char *product, exchange;
if(num1[0]=='0' || num2[0]=='0') return "0"; //節省腦細胞的特殊情況處理。
for(len1=0; num1[len1]!='\0'; len1++); //num1長度獲取
for(len2=0; num2[len2]!='\0'; len2++); //num2長度獲取
product = (char*)malloc(sizeof(char)*(len1+len2+1)); //積的空間分配,兩數相乘的長度有限
for(pos1=0; pos1<len1+len2+1; pos1++) product[pos1] = '\0'; //分配終止符,在後面還能作為判斷是否非空的條件
//開始計算乘積
for(pos1=len1-1; pos1>=0; pos1--){
for(pos2=len2-1; pos2>=0; pos2--){
if(product[(len1-pos1-1) + (len2-pos2-1)] == '\0') current = 0; //當前位的值
else current = product[(len1-pos1-1) + (len2-pos2-1)] - '0';
if(pos2 == len2-1) carry = 0; //前一次計算的進位
tempProduct = (num1[pos1]-'0') * (num2[pos2]-'0') + current + carry; //乘積
carry = tempProduct / 10; //本次計算的進位
current = tempProduct % 10; //本次計算後的當前位
product[(len1-pos1-1) + (len2-pos2-1)] = current + '0'; //值賦予
}
//處理每輪結束後的進位
if(carry!=0){
if(product[(len1-pos1-1) + (len2-pos2-1)] == '\0') current = 0;
else current = product[(len1-pos1-1) + (len2-pos2-1)] - '0';
tempProduct = current + carry;
current = tempProduct % 10;
product[(len1-pos1-1) + (len2-pos2-1)] = current + '0';
}
}
for(len1=len1+len2-1; product[len1]!='\0'; len1++); //實際結果長度計算
for(pos1=0; pos1<len1/2; pos1++){ //顛倒結果字串,使其為正序
exchange = product[pos1];
product[pos1] = product[len1-1-pos1];
product[len1-1-pos1] = exchange;
}
return product;
}