10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【C++】N進数で表現された数値をM進数に変換する

Last updated at Posted at 2021-02-21

#背景
競技プログラミング、ちょくちょく進数変換をする機会がありますよね。
2進→10進変換とか16進→2進変換とか、よくある数値ならいいのですが、
たまに中途半端な数字の進数変換を求められることがあります。
そんなときのために、任意の進数から任意の進数へ変換する関数を作りました。
テストは最低限の確認しかしていないので、抜け漏れあるかも。

#使い方

  • #include<string> が必要です。
  • 入力文字列は最大36進数の文字(0〜9,A,B,...,Z)まで対応しています。
  • 入力文字列を37進数以上と見なすことも可能です。
  • 出力は36進数までの対応です。
  • 不正入力に対するエラーは、実装していません。(時間があればやる)
2進数の数値"10110011"を10進数に変換する
n_ary("10110011", 2, 10); //出力値:179
10進数の数値"511"を16進数に変換する
n_ary("511", 10, 16); //出力値:1FF
36進数の数値"5Z"を10進数に変換する
n_ary("5Z", 36, 10); //出力値:215
1,000,000進数の数値"5XZ"を10進数に変換する
n_ary("5XZ", 1000000, 10); //出力値:5,000,033,000,035

#ソースコード
###メイン処理:string n_ary(string, int, int)
!自作関数を3つ使用しています。コピペで使用する際は後述のサブルーチンも合わせて使ってください!

n_ary(string,int,int)
/*  関数名          n_ary(string str, int n, int m)
    説明            n 進数で表現された数値を文字列 str で受け取り、m 進数に直して文字列で出力する。
    使用ライブラリ  string
    使用自作関数    ntodec, decton, pow_ll
    制約事項        36進数までの対応。負の値には対応していない。
*/
string n_ary(string str, int n, int m){
    unsigned long tmp = 0;
    string ret;

    for(int i=0; i<str.length(); i++){
        tmp += (unsigned long) ntodec(str[str.length()-1-i]) * pow_ll(n, i);
    }

    if(tmp==0) return "0";
    while(tmp!=0){
        ret = decton(tmp%m) + ret;
        tmp/=m;
    }
    return ret;
}

###サブルーチン1:N進→10進変換 (N≦36)
文字 0〜9, A〜Z を 0〜35 の整数に変換する関数です。

クリックでソースコードを表示
/*  関数名          ntodec(const char c)
    説明            char で 文字{0,1,2,...,9,A,B,...,Z} を受け取り、
            int で {0,1,2,...9,10,11,...,35}に直して返す。
            それ以外の文字が来た場合は-1を返す。
    使用ライブラリ   なし
*/
int ntodec(const char c){
    switch(c){
        case '0': return 0;
        case '1': return 1;
        case '2': return 2;
        case '3': return 3;
        case '4': return 4;
        case '5': return 5;
        case '6': return 6;
        case '7': return 7;
        case '8': return 8;
        case '9': return 9;
        case 'A': return 10;
        case 'B': return 11;
        case 'C': return 12;
        case 'D': return 13;
        case 'E': return 14;
        case 'F': return 15;
        case 'G': return 16;
        case 'H': return 17;
        case 'I': return 18;
        case 'J': return 19;
        case 'K': return 20;
        case 'L': return 21;
        case 'M': return 22;
        case 'N': return 23;
        case 'O': return 24;
        case 'P': return 25;
        case 'Q': return 26;
        case 'R': return 27;
        case 'S': return 28;
        case 'T': return 29;
        case 'U': return 30;
        case 'V': return 31;
        case 'W': return 32;
        case 'X': return 33;
        case 'Y': return 34;
        case 'Z': return 35;
        default : return -1;
    }
}

###サブルーチン2:10進→N進変換 (N≦36)
0〜35 の整数を文字 0〜9, A〜Z に変換する関数です。

クリックでソースコードを表示
/*  関数名          decton(const int n)
    説明            int で 数値 0〜35 を受け取り、文字{0,1,2,...,9,A,B,...,Z}に直して char で返す。
            それ以外の数字が来た場合は \0 を返す。
    使用ライブラリ  なし
*/
char decton(const int n){
    switch(n){
        case 0: return '0';
        case 1: return '1';
        case 2: return '2';
        case 3: return '3';
        case 4: return '4';
        case 5: return '5';
        case 6: return '6';
        case 7: return '7';
        case 8: return '8';
        case 9: return '9';
        case 10: return 'A';
        case 11: return 'B';
        case 12: return 'C';
        case 13: return 'D';
        case 14: return 'E';
        case 15: return 'F';
        case 16: return 'G';
        case 17: return 'H';
        case 18: return 'I';
        case 19: return 'J';
        case 20: return 'K';
        case 21: return 'L';
        case 22: return 'M';
        case 23: return 'N';
        case 24: return 'O';
        case 25: return 'P';
        case 26: return 'Q';
        case 27: return 'R';
        case 28: return 'S';
        case 29: return 'T';
        case 30: return 'U';
        case 31: return 'V';
        case 32: return 'W';
        case 33: return 'X';
        case 34: return 'W';
        case 35: return 'Z';
        default : return '\0';
    }
}

###サブルーチン3:べき乗計算(long long型)
long longで$x^n$を計算します。
std::powで桁数が足りないとき用に作ったものです。
double型で事足りる場合はstd::powで十分ですので、本関数は必須ではありません。

クリックでソースコードを表示
高速化を狙って`inline`にしてみたり。
/*  関数名          pow_ll(long long x, long long n)
    説明            x^n を計算する。long long 対応
    使用ライブラリ  なし
*/
inline long long pow_ll(long long x, long long n){
    long long ret = x;
    if(n==0) return 1;
    for(long long i=1; i<n; i++){
        ret *= x;
    }
    return ret;
}

#まとめ
この関数さえ仕込んでおけば、N進数からM進数への変換が簡単に行えると思います。
注意すべき点としては、以下でしょうか。

  • 小数に対応していない
  • 負の数に対応していない
  • 不正入力に対応していない
  • 雑なテストしかしていない(ごめんなさい)

ただし不正入力に関しては、decton()ntodec()において 0〜9、A〜Z 以外の入力があった場合に -1\0 をリターンする仕様になっているのでうまく利用してください。

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?