Skip to content

Instantly share code, notes, and snippets.

@jin-x
Created May 14, 2021 10:16
Show Gist options
  • Save jin-x/fdbc632aeee3b33e1212714edc7c3547 to your computer and use it in GitHub Desktop.
Save jin-x/fdbc632aeee3b33e1212714edc7c3547 to your computer and use it in GitHub Desktop.
@jinxonik / UniLecs #269
/***********************************************************************************************************************
Задача UniLecs №269: https://telegra.ph/Anons-269-CHisla-propisyu-05-14
Преобразование выполняется блоками по 1000, т.е. сначала миллиарды, затем миллионы, затем тысячи и, наконец, единицы.
В каждом блоке сначала проверяются сотни, затем значения 11..19, затем десятки, затем единицы.
Подробный алгоритм описан ниже.
1. Особый случай: если n = 0, возвращаем "zero".
2. Создаём пустую строку result. Если число меньше 0, заносим в неё слово "minus " и меняем знак у n.
3. Заводим переменную divisor = 1 млрд, хранящую делитель, а также переменную th_idx = 0, хранящую индекс текущей строки
с обозначением степеней тысячи (миллиард, миллион, тысяча).
4. Делим n на divisor, остаток записываем в n (для следующей итерации), частное (quot) будем использовать далее.
5. Если quot не меньше 100, значит у нас есть сотни --> добавляем слово из массива ones[quot/100-1], добавляем слово
"hundred ", а в quot записываем остаток от деления на 100.
6. Если quot находится в диапазоне от 11 до 19 --> добавляем слово teens[quot-11] и переходим к п.9.
7. Иначе если quot не меньше 10, значит у нас есть десятки --> добавляем слово из массива tens[quot/10-1], а в quot
записываем остаток от деления на 10.
8. Если quot больше 0, значит у нас есть единицы --> добавляем слово из массива ones[quot-1].
9. Если th_idx < размера массива thousands --> добавляем thousands[th_idx].
10. Делим divisor на 1000 (1 млрд --> 1 млн --> 1 тыс), увеличиваем th_idx на 1 и переходим к п.4, если divisor > 0.
11. Удаляем лишний пробел в конце строки (т.к. все слова у нас с пробелом на конце) и возвращаем результат.
***********************************************************************************************************************/
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
string int_to_eng(int32_t n)
{
if (n == 0) { return "zero"; } // special case
string result;
if (n < 0) { // negative numbers
result = "minus ";
n = -n;
}
const char* thousands[3] = { "billion ", "million ", "thousand " };
const char* hundred = { "hundred " };
const char* tens[9] = { "ten ", "twenty ", "thirty ", "forty ", "fifty ", "sixty ", "seventy ", "eighty ", "ninety " };
const char* teens[9] = { "eleven ", "twelve ", "thirteen ", "fourteen ", "fifteen ", "sixteen ", "seventeen ", "eighteen ", "nineteen " };
const char* ones[9] = { "one ", "two ", "three ", "four ", "five ", "six ", "seven ", "eight ", "nine " };
for (int32_t divisor = 1'000'000'000, th_idx = 0; divisor > 0; divisor /= 1000, ++th_idx) {
if (n >= divisor) {
auto r = std::div(n, divisor);
n = r.rem; // for the next iteration
if (r.quot >= 100) { // hundreds
result += ones[r.quot / 100 - 1];
result += hundred;
r.quot %= 100;
}
if (r.quot > 10 && r.quot < 20) { // teens
result += teens[r.quot - 11];
} else {
if (r.quot >= 10) { // tens
result += tens[r.quot / 10 - 1];
r.quot %= 10;
}
if (r.quot > 0) { result += ones[r.quot - 1]; } // ones
}
if (th_idx < sizeof(thousands)/sizeof(*thousands)) { // billion/million/thousand suffix
result += thousands[th_idx];
}
} // if (n >= divisor)
} // for
result.pop_back(); // remove last space
return result;
}
int main()
{
cout << "Enter a number from -2 billion to 2 billion: ";
int32_t n;
cin >> n;
cout << int_to_eng(n) << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment