' P '

whatever I will forget

アルファベットを26進数として扱う

atcoder.jp
で撃沈でした!

問題

端的に言うと、数字が与えられるので、それに対応するアルファベットを出力せよ。という問題
例えば、1ならa、27ならaaみたいな感じ。

これも覚えておけば次使えるテクニックなので、めもめも。

アルファベットは26進数である

よくわからんこと言ってますが、
- 1~26までがA~Zに対応します。
- 26+1~pow(26,2)+pow(26,1)がAA~ZZに対応します。
- pow(26,2)+pow(26,1)+1~pow(26,3)+pow(26,2)+pow(26,1)がAAA~ZZZに対応します。(あとは省略)

で、例えば27のAAなんですが、下記の10進数のそれぞれの値の和を出すような感じで、実は%26で与えられた数字のmodを'a'に足して変換していくだけ。

10進数の和を求めるときは、与えられた数字に対して、
n % 10を行ってそれのsumを求める。そしてnを10で割って、、を繰り返すだけである

例えば、27が与えられたとする。
1. 27 % 26をする。値は1。もし1=aとするならば、一桁目の文字はaとなる。
2. 27 / 26をする。値は1.
3. 1. をまた行う。1%26なので、値は1。二桁目の文字はaとなる。
4. 答えはaaになる。 エクセルとかの列表記を考えるとわかりやすい。
f:id:mankozooyork:20200622000805p:plain

プログラムとしては

modで求めた値は、'a'から何個目の文字なのか?示しているので、

char tmp = (char)(n%26 + 'a');

となるため、modの値か、元々のnの値を-1してあげる必要がある。
(27を例に挙げると、そのまま+1してしまうと、'a'はasciiで97のため、98となってしまい、bとなってしまう)

www.asciitable.com

あと、Stringなどに突っ込む場合は、突っ込んだ値は反転しているので、reverseしてあげる必要があります。

サンプル

import java.util.Scanner;

public class Main15 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long n = sc.nextLong();
        sc.close();

        StringBuilder sb = new StringBuilder();

        while(n > 0) {
            n--;
            sb.append((char)('a' + n % 26));
            n /= 26;
        }
        System.out.println(sb.reverse());
    }
}