Как перебрать последовательность букв в цикле? каждую последовательность нужно иметь возможность получить, зная номер позиции.
1=a
2=b
...
z=26
aa=27
ab=28
ac=29
...
и так до zzz
Что-то вроде системы счисления, но без цифр.
В вашей системе счисления, условно выражаясь, есть ведущие нули, но нет "внутренних" нулей. Ведущие нули присутствуют только в начале "времени жизни" разряда, т.е. как только разряд стал ненулевым, он уже никогда не станет нулевым.
Это позволяет нам использовать классический алгоритм перевода путем итеративного деления с остатком на основание системы счисления, не забывая при этом, что каждый разряд начинает свою жизнь в особом - "пустом"/"нулевом" - состоянии. Это отражается в том, что перед выполнением деления с остатком, надо вычесть из переводимого значения единицу. В это правило, кстати, естественным образом вписывается соглашение о том, что значению 0
соответствует пустая строка.
За исключением этого предварительного вычитания единицы, классический "школьный" алгоритм перевода остается неизменным
std::string convert_ascii(unsigned v, unsigned b)
{
std::string s;
for (; v > 0; v /= b)
{
--v; // предварительное вычитание единицы
s = (char) ('a' + v % b) + s;
}
return s;
}
Вот и все.
В вашем случае b = 26. Например, convert_ascii(12345678, 26)
дает нам zzjut
, а convert_ascii(322973, 26)
- rita
.
Оно похоже на просто систему счисления, но беда в том, что в ней нет нуля...
Вобщем, проще чем приведенное у меня что-то с утра не получается. Приходится учитывать, что a
- это не нуль...
string az(unsigned int num)
{
string s("");
--num; // Для отсчета с 0
s += 'a' + num%26; // Чередование последней буквы
if (num >= 26) // Есть вторая буква
{
num -= 26;
s += 'a' + num/26%26;
}
if (num >= 26*26) // Есть третья буква
{
num -= 26*26;
s += 'a' + num/(26*26);
}
reverse(s.begin(),s.end());
return s;
}
int main(int argc, const char * argv[])
{
for(unsigned int n = 1; n <= 18278; ++n)
cout << setw(5) << n << " " << az(n) << endl;
}
Update
Все, написал в общем виде, кратенько и красиво :)
string az(unsigned int num)
{
string s("");
for(unsigned int cnt = 1; num >= cnt; cnt *= 26)
s = char('a' + (num-=cnt)/cnt%26) + s;
return s;
}
Update 2
Только для @AnT :)
string div26(const string& d, unsigned int& r)
{
string q;
r = 0;
if (d.length() == 0) return q;
bool wroted = false;
for(size_t i = 0; i < d.length(); ++i)
{
r = r*10 + (d[i]-'0');
unsigned int v = r/26;
r %= 26;
if (!wroted && v == 0) continue;
q += char('0' + v);
wroted = true;
}
return q;
}
void dec(string& n)
{
if (n.length() == 0) return;
if (n.length() == 1 && n[0] == '0') return;
for(int i = n.length()-1; i >= 0; --i)
{
if (n[i] >= '1') { --n[i]; break; }
n[i] += 9;
}
size_t nz = n.find_first_not_of("0");
if (nz == string::npos) n = "";
else n = n.substr(nz);
}
string az(const string& number)
{
string res;
for(string n = number; n.length();)
{
dec(n);
unsigned int r;
n = div26(n,r);
res = char('a' + r) + res;
}
return res;
}
Проверяйте. Строка номер гугол: hxrtplbmwaiwcqlzpmglpziaegsdivmbvlnssusbjtbcgywaycqnhxztqwwikxvrsptazpp
Решение так сказать в лоб.
Это конечно не c++ и не delphi(это java), но идея в принципе думаю понятна.
public class Main {
public static void main(String[] args) {
int n = 26;
int iterator = 0;
int L = n + n * n + n * n * n; // общая длина массива
String[] code = new String[L + 1]; // сам массив
for (int i = 97; i <= 122; i++) { // заполняем для первой буквы
iterator++;
code[iterator] = String.valueOf((char) i);
}
for (int i = 97; i <= 122; i++) {// заполняем для второй буквы
for (int j = 97; j <= 122; j++) {
iterator++;
code[iterator] =(char) i +"" + (char) j;
}
}
for (int i = 97; i <= 122; i++) {// заполняем для третей буквы
for (int j = 97; j <= 122; j++) {
for (int k = 97; k <= 122; k++) {
iterator++;
code[iterator] = ""+(char) i + (char) j + (char) k;
}
}
}
Scanner scanner=new Scanner(System.in);
System.out.println(code[scanner.nextInt()]); // выводим на консоль нужный символ
}
}
Вывод всё как надо: 1 a 26 z 1000 all 27 aa
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Что может означать операция i = i & (i+1) в реализации дерева отрезков?
Здравствуйте! У меня есть задание написать дочерний класс Треугольник от класса УголКласс Угол уже готов, но у меня есть задание: имея класс...
Не удаётся найти компонент TDBGrid в Embarcadero C++ Builder 102
Мне нужно использовать готовый C++ класс CatalogИспользуя статью сделал начальную настройку проекта