Как упростить проверку на все арабские цифры в произвольной строке?

#include <iostream>

using namespace std;


void check_rule(char* MyLine)
{
    if ((strchr(MyLine, '1') && (strchr(MyLine, '2') && (strchr(MyLine, '3') && (strchr(MyLine, '4') && (strchr(MyLine, '5') && (strchr(MyLine, '6')
        && (strchr(MyLine, '7') && (strchr(MyLine, '8') && (strchr(MyLine, '9') && (strchr(MyLine, '0'))))))))))))
    {
        cout << "В строке есть все арабские цифры" << endl;
    }
    else
    {
        cout << "В строке не все арабские цифры" << endl;
    }

}



int main()
{
    setlocale(LC_ALL, "Russian");

    //char TestLine[100] = "sajsafhasfsafasufa213453456345789056735421dssa  \\|\?dasd123";
    char MyLine[100];

    cout << "Введите символы для проверки" << endl;

    gets_s(MyLine);

    cout << "Введенные символы для проверки " << MyLine << endl;

    check_rule(MyLine);

    return 0;
}

Ответы (3 шт):

Автор решения: Harry

Ну, например, так:

bool check_rule(const char* MyLine)
{
    for(char c = '0'; c <= '9'; ++c)
        if (strchr(MyLine,c) == nullptr) return false;
    return true;
}

Но, возможно, лучше сканировать всю строку и проверять наличие цифр - все равно strchr такое сканирование выполняет, так зачем терять уже просмотренные результаты? типа

bool check_rule(const char* MyLine)
{
    bool dig[10] = { false };
    for(const char *c = MyLine; *c; ++c)
        if (isdigit(*c)) dig[*c-'0'] = true;

    bool ok = true;
    for(int i = 0; i < 10; ++i) ok &= dig[i];

    return ok;
}

Если о строках что-то известно дополнительно - что встречается чаще, строки с полным набором или нет, очень длинные или нет etc - можно подумать над другими вариантами, или поэкспериментировать, что будет быстрее.

P.S. Я просто возвращаю из функции значение в соответствии с принципом, что каждая функция должна заниматься одним делом. Эта - проверяет выполнение правила, выводить строки на экран - дело другой функции.

Update

Для непонятливых...

void check_rule(const char* MyLine)
{
    for(char c = '0'; c <= '9'; ++c)
        if (strchr(MyLine,c) == nullptr) 
        {
            cout << "В строке не все арабские цифры" << endl;
            return;
    }
    cout << "В строке все арабские цифры" << endl;
}

void check_rule(const char* MyLine)
{
    bool dig[10] = { false };
    for(const char *c = MyLine; *c; ++c)
        if (isdigit(*c)) dig[*c-'0'] = true;

    bool ok = true;
    for(int i = 0; i < 10; ++i) ok &= dig[i];

    if (ok) cout << "В строке все арабские цифры" << endl;
    else    cout << "В строке не все арабские цифры" << endl;
    
}
→ Ссылка
Автор решения: user7860670

Можно сделать сопоставление значения цифры и булевого флажка, встретилась она или нет. Такой подход позволит обработать входную строку за один проход.

#include <array>
#include <cstddef>

void check_rule(char const * psz_text)
{
    ::std::array<bool, 10> map{};
    ::std::size_t count{};
    for (;;)
    {
        if ('\0' == *psz_text)
        {
            ::std::cout << "В строке не все арабские цифры" << ::std::endl;
            break;
        }
        if (('0' <= *psz_text) && (*psz_text <= '9'))
        {
            auto & entry{map[*psz_text - '0']};
            if (not entry)
            {
                ++count;
                if (map.size() == count)
                {
                    ::std::cout << "В строке есть все арабские цифры" << ::std::endl;
                    break;
                }
                entry = true;
            }
        }
        ++psz_text;
        continue;
    }
}
→ Ссылка
Автор решения: magrif

Как вариант

void check_rule(char const* myLine)
{
    // Флаг, каждый бит которого отражает встречающуюся цифру в строке
    unsigned short flag = 0;
    //макрос для экономии места
    //выполняет побитовое ИЛИ с флагом, где каждый бит отражает цифру
    //и проверяет, равен ли флаг значению 1023 (1111111111 в бинарном виде), 
    //что свидетельствует о том, что все цифры встречаются
#define CHECK(b) flag |= b; \
                 if(flag == 1023) { \
                    std::cout << "В строке есть все арабские цифры" << std::endl; \
                    return; \
                 }
    while(*myLine) {
        switch (*myLine) {
            case '0': CHECK(1)   break;
            case '1': CHECK(2)   break;
            case '2': CHECK(4)   break;
            case '3': CHECK(8)   break;
            case '4': CHECK(16)  break;
            case '5': CHECK(32)  break;
            case '6': CHECK(64)  break;
            case '7': CHECK(128) break;
            case '8': CHECK(256) break;
            case '9': CHECK(512)
        }
        ++myLine;
    }
    std::cout << "В строке не все арабские цифры " << std::endl;
}
→ Ссылка