這類問題的相同之處在於,數的大小超出了原生數據類型所能表示的範圍。如果用Python或者Java,就不必再看下去了。。。。。。
大數的模冪運算
給定x和y,求x的y次冪模k的餘數
unsigned int quick_power_mod(unsigned int x, unsigned int y, unsigned int k)
{
unsigned int res = 1;
x %= k;
while(y != 0)
{
if(y & 1)
{
res = (res * x) % k;
}
y >>= 1;
x = (x * x) % k;
}
return res;
}
這種做法的道理如下,指數y的二進制表示爲:
那麼
又因爲模運算有如下性質
於是我們有
該算法即在按照上式從左到右一項一項的計算。體現爲,遍歷y的每一個二進制位,如果該位爲1,將當前的計算結果乘以當前x的值並求餘,如果該位爲0,則不乘或者說乘以1;每遍歷y的一位,將x做一次平方,對應着上式中依次乘2的x的指數。
大數的進制轉換
給定a進制的數x(字符串形式),轉換爲b進制的數y
// big-endian for input
// small-endian for output
unsigned int convert_base(std::vector<unsigned int> &from_num, std::vector<unsigned int> &to_num, unsigned int from_base, unsigned int to_base)
{
for(int i = 0; i < from_num.size(); )
{
int carry = 0;
for(int j = i; j < from_num.size(); j++)
{
int tmp = (from_num[j] + carry * from_base) % to_base;
from_num[j] = (from_num[j] + carry * from_base) / to_base;
carry = tmp;
}
to_num.push_back(carry);
while(from_num[i] == 0)
{
i++;
}
}
}
此處使用的是除k取餘法,輸入的vector也被改變了,用來存儲每步計算的商。