兩大數相加,一大一小相乘,相除,取餘,這類的大數相對簡單,只需要用字符串細心模擬計算過程即可。
m轉n進制:
- 先將m進制轉10進制:
- 從低位到高位遍歷m進制每一位,乘以相應的權值(m^0, m^1…)加和即可
- 在將10進制轉化爲n進制:
- 除n取餘法
如果加上 大數 , 就先將主體寫清楚,具體的加法,乘除,取餘,就用大數模擬。
詳細的寫在代碼註釋:
#include <bits/stdc++.h>
using namespace std ;
const int AX = 1e6 + 666 ;
char s[AX] ; // 存儲要轉爲n進制的m進制大數
char res[AX] ; // 存儲10->n進制的結果
int a[AX] , b[AX] ; // a[]:在m轉10進制過程中,存儲每次的s[i]*m^base b[]:存儲m進制轉爲10進制的結果
int k , kb , tot ; // k : a[]索引,kb:b[]索引 , tot : res[]索引
int m , n ; // m -> n 進制
void add() { //大數加法:兩個大數存於a[],b[],結果覆蓋在b[],長度kb(索引起止:1->kb)
int len = max( k , kb );
int c = 0 ;
for( int i = 1 ; i <= len ; i++ ) {
b[i] = b[i] + a[i] + c ;
c = b[i] / 10000 ;
b[i] %= 10000 ;
}
if( c ) b[++len] += c ;
kb = len ;
}
/*大數乘法(一個大數,一個非大數<這裏是進制m和m進制每位置的數>相乘),
結果存於a[],長度k,索引起止 1-k*/
void mul( int num , int x ) {
for( int i = 1 ; i <= num ; i++ ) { //從低位到高位,冪次爲num,則乘num次(m^num)
int c = 0 ;
for( int j = 1 ; j <= k ; j++ ) {
a[j] = a[j] * x + c ;
c = a[j] / 10000 ;
a[j] %= 10000 ;
}
if( c ) a[++k] = c ;
}
}
/*大數取餘,一個大數存於b[],要轉n進制,故對非大數n取餘*/
int module() {
int remain = 0 ;
for( int i = kb ; i >= 1 ; i-- ) { //從高位開始除,模擬除法過程
int t = ( remain * 10000 + b[i] ) / n ; //因爲從高位,且每個位置存10000,故餘數*10000
int r = ( remain * 10000 + b[i] ) % n ;
remain = r ;
}
return remain ;
}
/*大數除法,一個大數存於b[],要轉n進制,除以n*/
void div() {
int remain = 0 ;
for( int i = kb ; i >= 1 ; i-- ) {
int t = ( remain * 10000 + b[i] ) / n ;
int r = ( remain * 10000 + b[i] ) % n ;
b[i] = t ;
remain = r ;
}
for( int i = 1 ; i <= kb ; i++ ) { //去除高位0
if( !b[i] ) {
kb = max( 0 , i - 1 ) ;
break ;
}
}
}
void ten_to_n() { // 10進制b[]轉n進制的除n取餘法主體,結果存於res[],長度tot,索引起止[0,tot).
tot = 0 ;
while(1) {
int r = module() ; //b[]對n取餘,結果存於r
if( r >= 10 ) res[tot++] = r - 10 + 'A';
else res[tot++] = r + '0' ;
div(); //對b[]做除法
if( !b[kb] ) break ; //被除數爲0,跳出循環
}
}
void m_to_ten( int len ) { //m進制轉10進制
int base = 0 ; //每位對應的權,如2轉10進制,第一位2^0 ,第二位2^1...
kb = 1 ;
memset( b , 0 ,sizeof(b) );
for( int i = len - 1 ; i >= 0 ; i-- ) {
k = 1 ;
a[1] = 1 ;
int x ;
mul(base,m) ;//得到每一位處要乘的權值
if( s[i] >= '0' && s[i] <= '9' ) x = (int)(s[i]-'0'); //處理10進制以上的符號表示
else {
if( s[i] >= 'a' && s[i] <= 'z' ) s[i] = s[i] - 'a' + 'A' ;
x = ( 10 + (int)(s[i]-'A') ) ;
}
mul(1,x); //將每一位x與權相乘
add(); //加和每次的x*m^base,得到b[],即10進制形式
base ++ ;
}
ten_to_n(); //m進制轉十進制成功,存於b[],開始用10進制轉n進制
}
int main() {
scanf("%d",&m);
scanf("%s",s);
scanf("%d",&n);
int len = strlen(s);
m_to_ten(len);
/*
print the result of m_to_len : verified 測試轉10進制結果
int f = 0 ;
for( int i = kb ; i >= 1; i-- ) {
if( i == k && !b[i] ) continue ;
if( f ) printf("%04d",b[i]);
else {
printf("%d",b[i]);
f = 1 ;
}
}
printf("\n");
*/
for( int i = tot - 1 ; i >= 0 ; i-- ) { //最終10進制轉n進制的結果
printf("%c",res[i]);
}
printf("\n");
return 0 ;
}