Как упростить большое условное утверждение - PullRequest
0 голосов
/ 31 октября 2019

Это условное утверждение сравнивает буквы с числами в соответствии с клавиатурой старых кнопочных телефонов.

В этом утверждении каждое условие if-else является одинаковым. Как я могу сократить этот кусок кода?

//compares every name and pattern character
//every number represents some letters from latin alphabet
    if(lowch >= 97 && lowch <= 99 && pattern[ptrch] == '2'){
        ptrch++;
        mir++;
    }
    else if(lowch >= 100 && lowch <= 102 && pattern[ptrch] == '3'){
        ptrch++;
        mir++;
    }
    else if(lowch >= 103 && lowch <= 105 && pattern[ptrch] == '4'){
        ptrch++;
        mir++;
    }
    else if(lowch >= 106 && lowch <= 108 && pattern[ptrch] == '5'){
        ptrch++;
        mir++;
    }
    else if(lowch >= 109 && lowch <= 111 && pattern[ptrch] == '6'){
        ptrch++;
        mir++;
    }
    else if(lowch >= 112 && lowch <= 115 && pattern[ptrch] == '7'){
        ptrch++;
        mir++;
    }
    else if(lowch >= 116 && lowch <= 118 && pattern[ptrch] == '8'){
        ptrch++;
        mir++;
    }
    else if(lowch >= 119 && lowch <= 122 && pattern[ptrch] == '9'){
        ptrch++;
        mir++;
    }
    else if(lowch == '+' && pattern[ptrch] == '0'){
        ptrch++;
        mir++;
    }
    else{
        ptrch = 0;
        mir = 0;
    }
}

** ptrch-pattern char
* mir - совпадения подряд

Ответы [ 3 ]

2 голосов
/ 31 октября 2019

Определите макрос, который инкапсулирует сравнения, а затем используйте одно условие с ||.

#define MATCH(start, end, ch) (lowch >= start && lowch <= end && pattern[ptrch] == ch)
if (MATCH('a', 'c', '2') || 
    MATCH('d', 'f', '3') || 
    MATCH('g', 'i', '4') || 
    MATCH('j', 'l', '5') || 
    MATCH('m', 'o', '6') ||
    MATCH('p', 's', '7') ||
    MATCH('t', 'v', '8') ||
    MATCH('w', 'z', '9') ||
    MATCH('+', '+', '0')) {
    ptrch++;
    mir++;
} else {
    ptrch = 0;
    mir = 0;
}

Другой вариант - использовать массив структур.

struct key {
    char start,
    char end,
    char ch
} keys[] = {
    {'a', 'c', '2'},
    {'d', 'e', '2'},
    ...
    {'+', '+', '0'}
};

bool found = false;
for (int i = 0; i < sizeof keys/sizeof keys[0]; i++) {
    if (lowch >= keys[i].start && lowch <= keys[i].end && pattern[ptrch] == keys[i].ch) {
        ptrch++;
        mir++;
        found = true;
        break;
}
if (!found) {
    ptrch = 0;
    mir = 0;
}
1 голос
/ 31 октября 2019

Решение, которое вы могли бы рассмотреть, состоит в том, чтобы отобразить буквы в массиве.

// . . . . . . . . . . abcdefghijklmnopqrstuvwxyz
const char* numbers = "22233344455566677778889999";

char digit = (lowch >= 'a' && lowch <= 'z') ? numbers[lowch - 'a'] : 0;
if (digit == pattern[ptrch]) {
    ptrch++;
    mir++;
}
else if(lowch == '+' && pattern[ptrch] == '0') {
    ptrch++;
    mir++;
}
else {
    ptrch = mir = 0;
}

Или (немного излишне) вы можете создать полную таблицу для обработки любого символа ...

// Build the table once
char dialpad[1 << CHAR_BIT] = { 0 };
const unsigned char *map_from = "abcdefghijklmnopqrstuvwxyz+";
const char          *map_to   = "222333444555666777788899990";

for (int i = 0; map_from[i]; i++) dialpad[map_from[i]] = map_to[i];

// Later on...
if (dialpad[(unsigned char)lowch] == pattern[ptrch]) {
    ptrch++;
    mir++;
}
else {
    ptrch = mir = 0;
}
0 голосов
/ 31 октября 2019

Все ваши символы (кроме знака плюс) состоят из строчных букв. В ASCII эти буквы находятся в непрерывном диапазоне. Поэтому вы можете использовать массив для сопоставления строчных букв с числовым кодом:

//                     abcdefghijklmnopqrstuvwxyz
const char code[26] = "22233344455566677778889999";

if (lowch >= 'a' && lowch <= 'z' && code[lowch - 'a'] == pattern[ptrch]) {
    ptrch++;
    mir++;
} else if (lowch == '+' && pattern[ptrch] == '0') {
    ptrch++;
    mir++;
} else{
    ptrch = 0;
    mir = 0;
}

Перед доступом к массиву необходимо проверить, является ли lowch действительной строчной буквой. Знак плюс здесь должен рассматриваться как особый случай. (Но вы можете сделать массив покрывающим весь 7-битный диапазон ASCII, где символы, не имеющие кода umber, имеют специальное значение, например '\0'.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...