🧮
26進数を使って列番号をExcelの列コードに変換する【C & Python】
Excelの列コードのような数え方の名前
Excelの列コードのようにA~Zまで行ったらAA~AZ, BA~BZ, ZA~ZZその次はAAA~みたいに増えていく数え方は「辞書式配列法」と呼ぶらしいです。
考え方
C言語
以下のサイトで実際に実行できます
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int Line = 702; // 列番号。Excelだと 895はAHK, 702はZZ になるはず。
div_t QuotAndRem; // 商と余りが入る構造体
int Remainder[256] = {}; // 余りが計算された順に1文字ずつ格納される配列
int Quotient = 0; // 商
int ArraySize = 0; // 余りが格納された配列Remainderの個数(終端記号は含まない)
int i = 0;
int j = 0;
int Num[256] = {}; // 前後順番を入れ替えられたRemainderが格納される配列
char Word[256] = {}; // Excelの列ワード
QuotAndRem = div(Line, 26); // 列番号を26で割った商と余りを構造体に入れる
Remainder[0] = QuotAndRem.rem; // 構造体から余りを代入
Quotient = QuotAndRem.quot; // 構造体から商を代入
// 商が0になるまでループ
while (Quotient != 0)
{
i++;
QuotAndRem = div(Quotient, 26); // 列番号を26で割った商と余りを構造体に入れる
Remainder[i] = QuotAndRem.rem; // 構造体から余りを配列に追加
Quotient = QuotAndRem.quot; // 構造体から商を代入
}
ArraySize = i + 1; // 余りが格納されている配列の数
///////////////////////////// 余りが0になってしまった時の処理 はじまり /////////////////////////////
//for (i = 0; i < ArraySize; i++){ fprintf(stdout, "余り0の対策前のRemainder[%d] = %d\n", i, Remainder[i]); }
for (i = 0; i < ArraySize - 1; i++)
{
// 余りの桁目が文字に変換できない0だったら
if (Remainder[i] == 0)
{
Remainder[i] = 26; // 余りの桁目を26(文字のZ)に変える
Remainder[i + 1] = Remainder[i + 1] - 1; // 余りの次の目を1繰り下げる
}
// 余りの桁目が繰り下げられた-1だったら
if (Remainder[i] == -1)
{
Remainder[i] = 25; // 余りの桁目を25(文字のY)に変える
Remainder[i + 1] = Remainder[i + 1] - 1; // 余りの次の目を1繰り下げる
}
}
// もし一番大きい桁の数が0以下だったら
if (Remainder[ArraySize - 1] <= 0)
{
ArraySize--; // 余りが格納されている配列の数を1減らす
}
//for (i = 0; i < ArraySize; i++){ fprintf(stdout, "余り0の対策後のRemainder[%d] = %d\n", i, Remainder[i]); }
///////////////////////////// 余りが0になってしまった時の処理 おしまい /////////////////////////////
// 余りが入れられた配列Remainderを前後入れ替えてNumに格納
j = ArraySize - 1;
for (i = 0; i < ArraySize; i++)
{
Num[j] = Remainder[i];
j--;
}
//for (i = 0; i < ArraySize; i++){ fprintf(stdout, "Num[%d] = %d\n", i, Num[i]); }
// Numをアルファベットに変換してWordに格納 (ASCIIコードでは65がA、66がBになる)
for (i = 0; i < ArraySize; i++)
{
sprintf(&Word[i], "%c", Num[i] + 64);
fprintf(stdout, "Word[%d] = %c\n", i, Word[i]);
}
Word[ArraySize] = '\0'; // 配列の終端記号追加
// 答えを表示
fprintf(stdout, "\nExcelの列番号 %d は %s です!!\n", Line, Word);
return 0;
}
Python
Line = 702
Remainder = []
Remainder.append(int(Line % 26))
Quotient = int(Line // 26)
while 0 != Quotient:
Remainder.append(int(Quotient % 26))
Quotient = int(Quotient // 26)
for i in range(0, len(Remainder) - 1):
# 余りの桁目が文字に変換できない0だったら
if 0 == Remainder[i]:
Remainder[i] = 26 # 余りの桁目を26(文字のZ)に変える
Remainder[i + 1] = Remainder[i + 1] - 1 # 余りの次の目を1繰り下げる
# 余りの桁目が繰り下げられた-1だったら
if -1 == Remainder[i]:
Remainder[i] = 25 # 余りの桁目を25(文字のY)に変える
Remainder[i + 1] = Remainder[i + 1] - 1 # 余りの次の目を1繰り下げる
# もし一番大きい桁の数が0以下だったら要素を消去
if 0 >= Remainder[-1]:
del Remainder[-1]
# 余りが入れられた配列を逆順にする
Remainder.reverse()
Answer = [chr(Num + 64) for Num in Remainder]
print(Answer)
Discussion