Reputation: 95
This conditional statement compares letters with numbers according to the keyboard of old button-phones.
In this statement, every if-else condition is the same. How can I shorten this piece of code?
//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 - matches in a row
Upvotes: 0
Views: 144
Reputation: 29126
All your characters (except the plus sign) are lower-case letters. In ASCII, these letters are in a contiguous range. You can therefore use an array to map lower-case letters to a number code:
// 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;
}
Before accessing the array, you must check whether lowch
is a valid lower-case letter. The plus sign must be treated as special case here. (But you could make the array cover the whole 7-bit ASCII range, where the characters that don't have a umber code have a special value, perhaps '\0'
.)
Upvotes: 0
Reputation: 63471
A solution you might consider is to map the letters in an array.
// . . . . . . . . . . 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;
}
Or (slightly overkill) you could build a full table to handle any character...
// 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;
}
Upvotes: 1
Reputation: 781096
Define a macro that encapsulates the comparisons, and then use a single condition with ||
.
#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;
}
Another option would be to use an array of structures.
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;
}
Upvotes: 2