Как правильно согласовывать числительное и существительное в языке C++ (например, "1 пирожок", "2 пирожка" и так далее)?

Какова правильность моего решения задачи отображения угла, установленного потенциометром, на экране с добавлением слова "градусов"? Мое текущее решение использует два массива с исключениями и выводит стандартное окончание в случае, если значение угла не попадает в эти исключения. Как можно улучшить данное решение, особенно в случае расширения диапазона значений, например, от 0 до 10000, когда количество исключений существенно возрастает?
  • 21 февраля 2025 г. 21:24
Ответы на вопрос 4
В языке C++ для правильного согласования числительного и существительного необходимо учитывать формы слов в зависимости от чисел. Для русского языка существует несколько правил, которые можно упрощенно описать следующим образом:

1. **1** — использует родительный падеж единственного числа (м.р.) ("1 пирожок").
2. **2, 3, 4** — используется родительный падеж множественного числа, но с окончаниями "а" или "я" ("2 пирожка", "3 пирожка", "4 пирожка").
3. Числа **5 и более** — используют родительный падеж множественного числа, но с окончанием "ов" ("5 пирожков", "10 пирожков", "100 пирожков").

Для автоматизации этого процесса в C++ вы можете использовать функцию, которая будет принимать число и возвращать правильное слово с учетом чисел. Вот пример функции:

```cpp
#include <iostream>
#include <string>

std::string getPirozhokForm(int count) {
    int lastDigit = count % 10;
    int lastTwoDigits = count % 100;

    if (lastTwoDigits >= 11 && lastTwoDigits <= 14) {
        return "пирожков";
    } else if (lastDigit == 1) {
        return "пирожок";
    } else if (lastDigit >= 2 && lastDigit <= 4) {
        return "пирожка";
    } else {
        return "пирожков";
    }
}

int main() {
    int count;
    std::cout << "Введите количество пирожков: ";
    std::cin >> count;
    std::cout << count << " " << getPirozhokForm(count) << std::endl;
    return 0;
}
```

По поводу отображения угла, установленного потенциометром, можно использовать похожий подход. Например, при отображении углов в градусах:

1. Для "0", "1", "2", "3", "4" нужно использовать соответствующие формы "градус", "градуса" и "градусов".
2. Число "10", "11", "12", "13", "14" требует окончания "градусов".
3. Для чисел от 15 и больше просто использовать "градусов".

Вот пример реализации функции для работы с уголом:

```cpp
#include <iostream>
#include <string>

std::string getDegreeForm(int degree) {
    int lastDigit = degree % 10;
    int lastTwoDigits = degree % 100;

    if (lastTwoDigits >= 11 && lastTwoDigits <= 14) {
        return "градусов";
    } else if (lastDigit == 1) {
        return "градус";
    } else if (lastDigit >= 2 && lastDigit <= 4) {
        return "градуса";
    } else {
        return "градусов";
    }
}

int main() {
    int angle;
    std::cout << "Введите угол: ";
    std::cin >> angle;
    std::cout << angle << " " << getDegreeForm(angle) << std::endl;
    return 0;
}
```

Таким образом, это решение универсально и справляется со всеми числами, не требуя создания большого количества исключений. То есть вы можете добавлять диапазоны значений без значительных изменений в коде.
Держите общий принцип. На плюсы переделывайте самостоятельно. 
function plural(value, form1, form2, form5) {
    r100 = value % 100;
    r10 = value % 10;
    if (r100 > 10 && r100 < 20) {
        return form5;
    }
    if (r10 == 1) {
        return form1;
    }
    if (r10 >= 2 && r10 <= 4) {
        return form2;
    }
    return form5;
}

units = plural(degrees, "градус", "градуса", "градусов");
Зачем с этим страдать, почему нельзя сократить или использовать символьное обозначение? 

Но если очень хочется
Число кончается на 2, 3, 4 и предпоследняя цифра не 1 - градуса
Число кончается на 1 и предпоследняя цифра не 1 - градус
В остальных случаях - градусов

std::string getAngleRus(int number) {
    int lastDigit = number % 10;
    int secondLastDigit = (number / 10) % 10;

    if (secondLastDigit == 1) {
        return "градусов";
    }
    
    if (lastDigit == 1) {
        return "градус";
    } else if (lastDigit >= 2 && lastDigit <= 4) {
        return "градуса";
    }

    return "градусов";
}
А почему не запустить цикл от 0 до 90 и самому не посмотреть - является или не является?

Оно работает, а значит является. Но если что то работает, оно не обязательно правильное. Более "правильным" как раз будет решение со сравнением последних цифр, тк мое решение просто так масштабировать не получится ;-)
Похожие вопросы