目的
サンプルでデータを用意する際にA~ZときてAA~ZZ,AAA~ZZZとなるようなアルファベットの連番を作るためのプログラム
プログラム
fn main() {
const DATA_AMMOUNT: i32 = 100000;
for i in 1..=DATA_AMMOUNT {
let id = i;
let age = 20 + (i % 30);
let name = "田中";
let name_suffix = get_suffix(i);
println!("{},{}-{},{}", id, name, name_suffix, age);
}
}
fn get_suffix(index: i32) -> String {
let mut suffix: String = String::from("");
const ALPHABET_NUM: i32 = 26;
// 'A'のASCIIコードの値
const START_ASCII: i32 = 65;
let mut length: u32 = 1;
let mut base = index;
// 連番に対応するアルファベットの桁数計算
loop {
if base <= ALPHABET_NUM.pow(length) {
break;
}
base -= ALPHABET_NUM.pow(length);
length += 1;
}
// 2桁以上の計算
for i in 1..length {
// 今の桁数の基底になる値(26の桁数乗)
let unit = ALPHABET_NUM.pow(i);
// 下の桁数分の差分を補正
let mut base = index;
for j in 1..=i {
base -= ALPHABET_NUM.pow(j);
}
base = (base + ALPHABET_NUM.pow(i + 1) - 1) % ALPHABET_NUM.pow(i + 1);
let offset = base / unit;
let ascii: u8 = (START_ASCII + offset) as u8;
suffix.insert(0, ascii as char);
}
// 末尾の文字の計算
let offset = (index + ALPHABET_NUM - 1) % ALPHABET_NUM;
let ascii = (START_ASCII + offset) as u8;
suffix.insert(suffix.len(),ascii as char);
suffix
}
出力
1,田中-A,21
2,田中-B,22
3,田中-C,23
~中略~
25,田中-Y,45
26,田中-Z,46
27,田中-AA,47
28,田中-AB,48
29,田中-AC,49
30,田中-AD,20
~中略~
51,田中-AY,41
52,田中-AZ,42
53,田中-BA,43
54,田中-BB,44
~中略~
701,田中-ZY,31
702,田中-ZZ,32
703,田中-AAA,33
704,田中-AAB,34
~中略~
18277,田中-ZZY,27
18278,田中-ZZZ,28
18279,田中-AAAA,29
18280,田中-AAAB,30
~中略~
99999,田中-EQXC,29
100000,田中-EQXD,30
最後に
アルファベットを26進数として10進数から変換するというのが基本の考え方なのだろうけど、自分でやってみるとかなり苦戦しました。
もっと綺麗な書き方があると思いますが必要な連続アルファベットが得られたので良しとします。