C++を使用して、Excelシートの列番号を例に、10進数と全単射26進数を相互に変換する方法を説明します。
開発環境 | Visual Studio 2022 |
---|---|
言語 | C++ |
動作確認 | Windows 11 Windows 10 Windows 7 |
Ubuntu (g++) FreeBSD (clang++) |
Excelシートの列番号の最大値は、XFD(16384 = 214)です。以下のような並びになります。サンプルソースは、FXSHRXW(2147483647 = INT_MAXの値)まで対応します。
10進数 ; 1,2,...,25,26,27,28,...,701,702,703,704,...,16383,16384
全単射26進数; A,B,..., Y, Z,AA,AB,..., ZY, ZZ,AAA,AAB,..., XFC, XFD
10進数から全単射26進数
26で割った余りを、下の桁から上の桁に向かって、順番に並べていきます。数値とアルファベットの対応は、US-ASCII(A~Zは0x41~0x5A)から0x40を引きます。
(例)
16384 ÷ 26 = 630 余り 4 → D
630 ÷ 26 = 24 余り 6 → F
24 ÷ 26 = 0 余り 24 → X
より、XFD
ただし、全単射26進数はゼロに相当するアルファベットが無く、26で桁が繰り上がらないので、「余りゼロ」を「余り26」として計算します。
(例)
26 ÷ 26 = 1 余り 0
を
26 ÷ 26 = 0 余り 26 → Z
とする
#include <string>
std::string base10to26(int n)
{
int r = 0;
std::string str;
do
{
r = n % 26;
n /= 26;
if (!r)
{
r = 26;
n--;
}
str.insert(str.begin(), 0x40 + r);
}
while (n > 0);
return str;
}
全単射26進数から10進数
アルファベットに対応する数値を、26を「下から何桁目-1」乗した値と掛けて、合計します。
(例)
XFD → 24、6、4
24 × 263 – 1 + 6 × 262 – 1 + 4 × 261 – 1 = 16384
#include <cmath>
#include <string>
int base26to10(std::string str)
{
std::size_t size = str.size();
int n = 0;
for (std::size_t i = 0; i < size; i++)
{
n += (str[i] - 0x40) * static_cast<int>(std::pow(26, size - i - 1));
}
return n;
}
リファレンス
Bijective numeration
https://en.wikipedia.org/wiki/Bijective_numeration
「The bijective base-26 system」を参考にしました。