缩短计算二维数组中唯一字符数的函数

Shortening a function that counts the number of unique chars in a 2D array

我有一个函数,它通过循环计算二维数组中唯一字符的数量,并在每次找到有效字符数组中的字符时将一维数组的每个单元格中的计数增加 1。然后我遍历一维数组,每次找到一个数字大于 0 的单元格时,都会增加一个计数器。如果这个数字高于我的结构的height/width,它returns false.

'.'表示一个空的 space,虽然它在程序的方案中有效,但不应算作唯一字符。

我想知道是否有办法创建具有相同功能但更短的函数。

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;
}

声明一个字符数组或字符串文字,例如

const char *letters = "KRBGCYQM.";

然后使用在 header <string.h> 中声明的标准字符串函数 strchr like

char *p = strchr( letters, b->shelves[i][j] );
if ( p != NULL ) 
{
    if ( b->shelves[i][j] != '.' ) ++chars[p - letters];
}
else
{
    return false;
}

请注意,您的代码的读者不清楚为什么包含 '.' 字符,但未计算在内。

我可以建议使用位域而不是字符数组吗?像这样:-

present = 0
foreach char c in b->shelves
    if c is a uppercase letter
        present |= 1 << (c - 'A')
present &= valid letters bit pattern (this is a constant and is the or of 1 shifted by each letter)
return number of bits in present <= b->height

或者,如果您不喜欢那样,请使用开关而不是 if 测试序列:-

switch b->shelves[i][j]
    case 'K'
        ++chars[0]
    other cases for the valid letters
        ++chars[whatever]
    default:
        error - an invalid character