Как оптимизировать функции выбора окончаний и конвертации числа в словесное представление?
У меня есть код на C++, который осуществляет конвертацию чисел в их текстовое представление на русском языке. Но мне кажется, что некоторые части кода могут быть оптимизированы и улучшены.
Структуры "Endings" и "Numbers" содержат массивы строк, используемые для формирования словесных окончаний и числительных. Функция "chooseEnding" выбирает правильное окончание в зависимости от последних цифр числа. Функция "convertNumberToWords" осуществляет конвертацию числа в текст, используя структуры "Endings" и "Numbers".
struct Endings {
std::array<std::string, 3> rubleEndings = { " рублей", " рубль", " рубля" };
std::array<std::string, 3> thousandEndings = { " тысяч", " тысяча", " тысячи" };
std::array<std::string, 3> millionEndings = { " миллионов", " миллион", " миллиона" };
std::array<std::string, 3> billionEndings = { " миллиардов", " миллиард", " миллиарда" };
};
struct Numbers {
std::array<std::string, 10> units = { "", " один", " два", " три", " четыре", " пять", " шесть", " семь", " восемь", " девять" };
std::array<std::string, 10> unitsThousand = { "", " одна", " две", " три", " четыре", " пять", " шесть", " семь", " восемь", " девять" };
std::array<std::string, 10> teens = { " десять", " одиннадцать", " двенадцать", " тринадцать", " четырнадцать", " пятнадцать", " шестнадцать", " семнадцать", " восемнадцать", " девятнадцать" };
std::array<std::string, 10> tens = { "", "", " двадцать", " тридцать", " сорок", " пятьдесят", " шестьдесят", " семьдесят", " восемьдесят", " девяносто" };
std::array<std::string, 10> hundreds = { "", " сто", " двести", " триста", " четыреста", " пятьсот", " шестьсот", " семьсот", " восемьсот", " девятьсот" };
};
std::string chooseEnding(long long number, const std::array<std::string, 3>& endings) {
long long lastDigit = number % 10;
long long penultimateDigit = (number / 10) % 10;
if (penultimateDigit == 1) {
return endings[0];
}
else if (lastDigit == 1) {
return endings[1];
}
else if (lastDigit >= 2 && lastDigit <= 4) {
return endings[2];
}
else {
return endings[0];
}
}
std::string convertNumberToWords(long long number, Numbers& numbers, Endings& endings)
{
std::string handleError = "error";
std::string result;
const std::vector<std::pair<long long, std::array<std::string, 3>>> divisions = {
{ Constants::Billion, endings.billionEndings },
{ Constants::Million, endings.millionEndings },
{ Constants::Thousand, endings.thousandEndings }
};
for (const auto& division : divisions)
{
if (number >= division.first)
{
long long divisionResult = number / division.first; // Вычисляем результат деления заранее
if (division.first == Constants::Thousand && (divisionResult == 1 || divisionResult == 2))
result += numbers.unitsThousand[divisionResult] +chooseEnding(divisionResult, division.second);
else
result += convertNumberToWords(divisionResult, numbers, endings) + chooseEnding(divisionResult, division.second);
number %= division.first;
}
}
if (number >= Constants::Hundred)
{
result += numbers.hundreds[number / Constants::Hundred];
number %= Constants::Hundred;
}
if (number >= Constants::Twenty)
{
result += numbers.tens[number / Constants::Ten];
number %= Constants::Ten;
}
if (number >= Constants::Ten)
{
result += numbers.teens[number - Constants::Ten];
}
else if (number > 0)
{
result += numbers.units[number];
}
return result.empty() ? handleError : result;
}
Мои вопросы:
Как можно оптимизировать функцию "chooseEnding" для повышения эффективности?
Есть ли более лаконичные способы выразить логику выбора окончаний?
Какие методы оптимизации можно предложить для функции "convertNumberToWords"?
Есть ли общие структурные или стилевые советы по этому коду, которые можно было бы учесть
Как можно было бы переписать код, используя указатели на функции и стоит ли это того?
Буду очень благодарен за ваши ценные советы и рекомендации по улучшению данного кода. Спасибо!