C++でスプレッドシートの列番号から列名(A, B, …, Z, AA…)を求めるプログラム
スプレッドシートの列は、A、B、Cというようにアルファベット順にラベル付けされています。Zの次はAA、AB、…、ZZへと進み、その後はAAA、AAB、…と続いていきます。つまり、列番号1が「A」、列番号26が「Z」、列番号27が「AA」に対応します。
本記事では、列番号が与えられたときに、対応する列名(アルファベット表記)を求める方法をC++で解説します。例えば、列番号が80なら「CB」、30なら「AD」が出力されます。
考え方:26進法として扱う
一見すると単純な26進数への変換のように思えますが、注意が必要です。この体系には「0」に相当する文字が存在しないからです。A〜Zはそれぞれ1〜26に対応しており、0がありません。そのため、剰余が0になった場合のみ特別な処理を行います。
- n を26で割った余りが0の場合:「Z」を追加し、n を n÷26 − 1 に更新する
- それ以外の場合:(余り − 1) + 'A' の文字を追加し、n を n÷26 に更新する
これを n が0になるまで繰り返します。ループ内では下位の桁から順に文字が確定していくため、最後に文字列を反転させれば正しい列名が得られます。
C++での実装例
#include<iostream>
#include<algorithm>
using namespace std;
void showColumnLetters(int n) {
string str = "";
while (n) {
int rem = n % 26;
if (rem == 0) {
str += 'Z';
n = (n / 26) - 1;
} else {
str += (rem - 1) + 'A';
n = n / 26;
}
}
reverse(str.begin(), str.end());
cout << str << endl;
}
int main() {
int n = 700;
cout << "Cell name of " << n << " is: ";
showColumnLetters(700);
}入力
700
出力
Cell name of 700 is: ZX
動作の流れ(n = 700 の場合)
・1回目:700 ÷ 26 = 26 余り 24 → 余りが0でないため「X」を追加し、n = 26
・2回目:26 ÷ 26 = 1 余り 0 → 余りが0のため「Z」を追加し、n = 1 − 1 = 0
・ループ終了時点で文字列は「XZ」。これを反転して「ZX」が出力されます。
計算量
列名の桁数は26進法における桁数に相当するため、時間計算量・空間計算量はともに O(log26 n) となります。非常に大きな列番号でも高速に処理できるのが特徴です。
-
グリッド内で照らされているセルの数を求めるC++プログラム
問題の概要 ここでは、縦 h × 横 w のサイズを持つグリッドが与えられたとき、光で照らされているセルの数を求めるC++プログラムを紹介します。グリッドのセルには「電球」または「障害物」が置かれています。電球のあるセルは、そのセル自身と上下左右のセルを照らし、光は障害物に遮られない限りまっすぐ伝わっていきます。一方、障害物のあるセルは照らされることがなく、電球の光を遮って他のセルへ光が届かないようにします。電球の位置を配列 bulb、障害物の位置を配列 obstacles として受け取り、グリッド全体で照らされているセルの合計数を求めます。 たとえば、入力が h = 4、w = 4、bulb
-
C++で与えられた点から作成できる四角形の数を求める方法
四角形とは? 四角形(クアドララテラル)とは、ユークリッド平面上で4つの頂点と4つの辺を持つ多角形のことを指します。「4-gon」という呼び方もあり、正方形や長方形なども四角形の一種に含まれます。 本記事では、与えられた点から作成できる四角形の数を求める手法について解説します。この問題では、直交座標系(XY平面)上に与えられた4つの点 (x, y) を用いて、いくつの四角形を構成できるかを求めます。まず、具体的な入力例と出力例を見てみましょう。 入力 : A( -2, 8 ), B( -2, 0 ), C( 6, -1 ), D( 0, 8 ) 出力 : 1 説明 : 作成できる四角形は1つだ