Страницы

Поиск по вопросам

воскресенье, 29 декабря 2019 г.

Последовательность от a до zzz

#cpp #алгоритм #delphi


Как перебрать последовательность букв в цикле? каждую последовательность нужно иметь
возможность получить, зная номер позиции.

1=a

2=b

...

z=26

aa=27

ab=28

ac=29

...

и так до zzz

Что-то вроде системы счисления, но без цифр.
    


Ответы

Ответ 1



В вашей системе счисления, условно выражаясь, есть ведущие нули, но нет "внутренних" нулей. Ведущие нули присутствуют только в начале "времени жизни" разряда, т.е. как только разряд стал ненулевым, он уже никогда не станет нулевым. Это позволяет нам использовать классический алгоритм перевода путем итеративного деления с остатком на основание системы счисления, не забывая при этом, что каждый разряд начинает свою жизнь в особом - "пустом"/"нулевом" - состоянии. Это отражается в том, что перед выполнением деления с остатком, надо вычесть из переводимого значения единицу. В это правило, кстати, естественным образом вписывается соглашение о том, что значению 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.

Ответ 2



Оно похоже на просто систему счисления, но беда в том, что в ней нет нуля... Вобщем, проще чем приведенное у меня что-то с утра не получается. Приходится учитывать, что 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

Ответ 3



Решение так сказать в лоб. Это конечно не 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

Комментариев нет:

Отправить комментарий