【概述】
karatsuba乘法是一種快速乘法。此演算法在2023年由anatolii alexeevitch karatsuba 提出,並於2023年得以發表。
此演算法主要用於兩個大數相乘。普通乘法
的複雜度是n
2,而karatsuba演算法的複雜度僅為3nlog3
≈3n1.585
(log3是以2為底的)
【步驟】
karatsuba演算法主要應用於兩個大數的相乘,原理是將大數分成兩段後變成較小的數字,然後做3次乘法,並附帶少量的加法操作和移位操作。
現有兩個大數,x,y。
首先將x,y分別拆開成為兩部分,可得x1,x0,y1,y0。他們的關係如下:
x = x1 * 10
m + x0;
y = y1 * 10m + y0。其中m為正整數,m < n,且x0,y0 小於 10m。
那麼xy = (x1 * 10m + x0)(y1 * 10m + y0)
=z2 * 10
2m + z1 * 10m + z0,其中:
z2 = x1 * y1;
z1 = x1 * y0 + x0 * y1;
z0 = x0 * y0。
此步驟共需4次乘法,但是由karatsuba改進以後僅需要3次乘法。因為:
z1 = x1 * y0+ x0 * y1
z1 = (x1 + x0) * (y1 + y0) - x1 * y1 - x0 * y0,
故x0 * y0 便可以由加減法得到。
所以:x*y = z2 * 102m+ z1 * 10m +z0
z2 = x1 * y1
z1 = (x1 + x0) * (y1 + y0) - x1 * y1 - x0 * y0 =(x1 + x0) * (y1 + y0) - x1 * y1 - z0
z0 = x0 * y0
recursively computer (x1*y1)
recursively computer (x1 + x0) * (y1 + y0)
recursively computer (x0 * y0)
【例項講解】
設x = 12345,y=6789,令m=3。那麼有:
12345 = 12 * 1000 + 345;
6789 = 6 * 1000 + 789。
下面計算:
z2 = 12 * 6 = 72;
z0 = 345 * 789 = 272205;
z1 = (12 + 345) * (6 + 789) - z2 - z0 = 11538。
然後我們按照移位公式(xy = z2 * 102m + z1 * 10m+ z0)可得:
xy = 72 * 1000
2 + 11538 * 1000 + 272205 = 83810205。
【偽**】
procedure karatsuba(num1, num2)if(num1 <
10) or (num2 <10)
return num1*num2
/* calculates the size of the numbers */
m =max(size_base10(num1)
, size_base10(num2)
) m2 = m/
2/* split the digit sequences about the middle */
x1, x0 = split_at(num1, m2)
y1, y0 = split_at(num2, m2)
z0 = karatsuba(x0,y0
) z1 = karatsuba(
(x1+x0),
(y1+y0)
) z2 = karatsuba(x1,y1)
return
(z2*10^
(2*m2))+
((z1-z2-z0)*10
^(m2))+
(z0)
【**】
/*********************************
* 日期:2015-01-29
* 題目: karatsuba快速相乘演算法
* 部落格:
**********************************/
#include #include #include using namespace std;
// given two unequal sized bit strings, converts them to
// same length by adding leading 0s in the smaller string. returns the
// the new length
int makesamelen(string& num1,string& num2)//for
return len2;
}//if
else//for
return len1;
}//else
}// big number minus function
string minusstring(string num1, string num2) //if
// 正負
bool positive = true;
if(len1 < len2 || (len1 == len2 && num1 < num2))//if
string result;
int i = len1 - 1,j = len2 - 1;
int a,b,sum,carray = 0;
// 從低位到高位對位做減法
while(i >= 0 || j >= 0)//if
result.insert(result.begin(),sum + '0');
--i;
--j;
}//while
// 刪除前導0
string::iterator it = result.begin();
while(it != result.end() && *it == '0')//while
result.erase(result.begin(),it);
return positive ? result : "-"+result;
}// big number add function
string addstring(string num1,string num2)//if
if(len2 <= 0)
string result;
int i = len1-1,j = len2-1;
int a,b,sum,carry = 0;
// 倒序相加
while(i >= 0 || j >= 0 || carry > 0)//while
return result;
}// 移位
string shiftstring(string num,int len)//if
for(int i = 0;i < len;++i)//for
return num;
}// karatsuba快速相乘演算法
string karatsubamultiply(string num1, string num2) //if
// all digit are one
if(len == 1)//if
int mid = len / 2;
// find the first half and second half of first string.
string x1 = num1.substr(0,mid);
string x0 = num1.substr(mid,len - mid);
// find the first half and second half of second string
string y1 = num2.substr(0,mid);
string y0 = num2.substr(mid,len - mid);
// recursively computer
string z0 = karatsubamultiply(x0,y0);
string z1 = karatsubamultiply(addstring(x1,x0),addstring(y1,y0));
string z2 = karatsubamultiply(x1,y1);
// (z2*10^(2*m))+((z1-z2-z0)*10^(m))+(z0)
// z2*10^(2*m)
string r1 = shiftstring(z2,2*(len - mid));
// (z1-z2-z0)*10^(m)
string r2 = shiftstring(minusstring(minusstring(z1,z2),z0),len - mid);
return addstring(addstring(r1,r2),z0);
}int main(){
string num1("12345001");
string num2("1006789");
string result = karatsubamultiply(num1,num2);
// 輸出
cout<
九章演算法系列(一)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!問題 實現乙個memcpy函式 本題主要考慮兩點 1 記憶體重疊與否2 重疊記憶體的copy方式 無重疊的記憶體copy void mymemcpy void dst,const void src,size t num if des src num...
C 演算法系列之排序
插入排序 o n2 基本思路就是玩撲克牌的時候,從牌堆裡摸牌放到手上的思路 include include include include include include const int m 1000 const int n 1000 template void insertsort const...
經典演算法系列之 遞迴
1 前言 演算法,在計算機中的地位,就相當於人類大腦的決策中樞系統,哪怕最簡單的演算法,其精妙的思維方式,都可以讓人開啟一扇新的視窗。演算法,它不僅僅只是狹義的用來解決電腦科學領域的問題,更是一種 思維方式 演算法思維,是一種深度思考和創造的過程。演算法,只有真正理解了,而不只是所謂的知道,並將應用...