I have a function that counts the number of unique characters in a 2D array by looping over it and increasing the count in each cell of a 1D array by 1 each time a character from the valid char array is found. I then loop over the 1D array and each time a cell with a number higher than 0 is found, a counter is increased. If this number is higher than the height/width of my structure, it returns false.
'.' represents an empty space and whilst it is valid in the scheme of the program, it should not count as a unique character.
I was wondering if there was a way to create a function with the same functionality, but much shorter.
bool uniqueChars (Bookcase *b)
{
int i, j, chars[8] = {0}, cnt = 0;
char validChars[10] = {"KRGYBMCW."};
bNullPoint(b);
for (i = 0; i < b->height; i++) {
for (j = 0; j < b->width; j++) {
b->shelves[i][j] = toupper(b->shelves[i][j]); /* To aid with testing*/
if (strchr(validChars, b->shelves[i][j])) {
if (b->shelves[i][j] == 'K') {
chars[0] += 1;
}
if (b->shelves[i][j] == 'R') {
chars[1] += 1;
}
if (b->shelves[i][j] == 'B') {
chars[2] += 1;
}
if (b->shelves[i][j] == 'G') {
chars[3] += 1;
}
if (b->shelves[i][j] == 'C') {
chars[4] += 1;
}
if (b->shelves[i][j] == 'Y') {
chars[5] += 1;
}
if (b->shelves[i][j] == 'W') {
chars[6] += 1;
}
if (b->shelves[i][j] == 'M') {
chars[7] += 1;
}
} else {
return false;
}
}
}
for (i = 0; i < 8; i++) {
if (chars[i] > 0) {
cnt += 1;
}
}
if (cnt > b->height) {
return false;
}
return true;
}
Declare a character array or a string literal as for example
const char *letters = "KRBGCYQM.";
and then use the standard string function strchr
declared in the header <string.h>
like
char *p = strchr( letters, b->shelves[i][j] );
if ( p != NULL )
{
if ( b->shelves[i][j] != '.' ) ++chars[p - letters];
}
else
{
return false;
}
Pay attention to that it is unclear for readers of your code why the character '.'
is included though it is not counted.