Есть ли эффективный способ сравнить эти массивы? - PullRequest
1 голос
/ 07 апреля 2019

У меня есть сканер NFC, который получает UID тега и сохраняет его в byte TagReadB[4].

Затем мне нужно сравнить его с большим количеством других байтовых массивов, чтобы увидеть, совпадает ли он с ними (т.е.если это распознанный тег).

Распознанные теги сохраняются следующим образом.

uint8_t RED1[4] = {0x15, 0x4C, 0xA9, 0xFB};
uint8_t RED2[4] = {0x67, 0xFC, 0x8A, 0x16};
uint8_t RED3[4] = {0xB7, 0xC4, 0xEA, 0xA4};
uint8_t RED4[4] = {0xE7, 0x32, 0xE7, 0xA4};
uint8_t RED5[4] = {0x87, 0x33, 0xED, 0x74};
uint8_t RED6[4] = {0xB7, 0x56, 0xFA, 0xA4};
uint8_t RED7[4] = {0xB5, 0x8A, 0xB6, 0xFB};
uint8_t RED8[4] = {0x07, 0xA6, 0xF3, 0xA4};
uint8_t RED9[4] = {0xE5, 0xB2, 0x9E, 0xFB};
uint8_t RED10[4] = {0x87, 0xF8, 0x8A, 0x16};
uint8_t RED11[4] = {0x47, 0x93, 0xDA, 0xA4};
uint8_t RED12[4] = {0x87, 0x1D, 0x8A, 0x16};
uint8_t RED13[4] = {0x85, 0x83, 0xB1, 0xFB};
uint8_t RED14[4] = {0x55, 0x33, 0x9C, 0xFB};
uint8_t RED15[4] = {0x45, 0x39, 0xB7, 0xFB};
uint8_t RED16[4] = {0xA5, 0xED, 0xA5, 0xFB};
uint8_t RED17[4] = {0x85, 0x6E, 0xA1, 0xFB};
uint8_t RED18[4] = {0x17, 0xC3, 0xEF, 0xA4};
uint8_t RED19[4] = {0x37, 0xCA, 0xEB, 0xA4};
uint8_t RED20[4] = {0x15, 0x66, 0xA0, 0xFB};
uint8_t YELLOW1[4] = {0x27, 0x44, 0x73, 0xE5};
uint8_t YELLOW2[4] = {0xD7, 0x44, 0xCB, 0xE2};
uint8_t YELLOW3[4] = {0x87, 0x6E, 0x78, 0xE5};
uint8_t YELLOW4[4] = {0x27, 0x49, 0x63, 0xE5};
uint8_t YELLOW5[4] = {0xA7, 0x0D, 0x6C, 0xE5};
uint8_t YELLOW6[4] = {0x87, 0x96, 0x69, 0xE5};
uint8_t YELLOW7[4] = {0x37, 0xF9, 0xCA, 0xE2};
uint8_t YELLOW8[4] = {0xD7, 0xAE, 0xCB, 0xE2};
uint8_t YELLOW9[4] = {0xA7, 0xE3, 0x78, 0xE5};
uint8_t YELLOW10[4] = {0x47, 0x72, 0x90, 0xE5};
uint8_t BLUE1[4] = {0x73, 0xD5, 0xB7, 0xAC};
uint8_t BLUE2[4] = {0x1D, 0x5D, 0xFC, 0x69};
uint8_t BLUE3[4] = {0xBD, 0xEC, 0x8F, 0x12};
uint8_t BLUE4[4] = {0xE6, 0x9F, 0x54, 0x73};
uint8_t BLUE5[4] = {0x38, 0x74, 0x7E, 0x33};
uint8_t BLUE6[4] = {0x6D, 0x05, 0x3E, 0x12};
uint8_t BLUE7[4] = {0x9C, 0x6B, 0x4A, 0x73};

Я могу сделать следующее, но должен быть более простой способ без необходимости повторять 20 операторов ИЛИ?

if (!memcmp(TagReadB, RED1, 4) || !memcmp(TagReadB, RED2, 4) || ...)    {

        //do something

    }

Еще лучше, было бы здорово проверить, с каким цветом распознанного тега он совпадает, потому что для каждого цвета будет одинаковое действие.

например, если это красныйтег do x, желтый тег do y, синий тег do z.

Большое спасибо.

Ответы [ 2 ]

1 голос
/ 07 апреля 2019

Вы можете расширить свои данные до

struct {uint8_t tag[4], uint8_t type}
data[] = {
   { {0x15, 0x4C, 0xA9, 0xFB}, RED}, 
// ...
   { {0xD7, 0xAE, 0xCB, 0xE2}, YELLOW },
// ...
};

с

#define RED 1
// etc. 

(или константный байт или перечисление)

Затем зациклите этот список до совпадения и верните полученный результат data[i].type или верните 0 для "not found"

0 голосов
/ 07 апреля 2019

Вы можете хранить теги в многомерных массивах:

uint8_t RED_TAGS[][4] = {
    {0x15, 0x4C, 0xA9, 0xFB},
    {0x67, 0xFC, 0x8A, 0x16},
    ...
};

uint8_t YELLOW_TAGS[][4] = {
    {0x15, 0x4C, 0xA9, 0xFB},
    {0x67, 0xFC, 0x8A, 0x16},
    ...
};

uint8_t BLUE_TAGS[][4] = {
    {0x15, 0x4C, 0xA9, 0xFB},
    {0x67, 0xFC, 0x8A, 0x16},
    ...
}

Теперь вы можете проверить наличие тега в одном из многомерных массивов, используя цикл for:

int is_tag_in_array(uint8_t array[][4], int size, uint8_t tag[4]) {
    for (int i=0;i<size;i++) {
        if (memcmp(array[i], tag, 4) == 0)
            return 1;
    }
    return 0;
}

Таким образом, вы можете проверить цвет следующим образом:

if (is_tag_in_array(RED_TAGS, 20, TagReadB)) {
    // Do something for a red tag
} else if (is_tag_in_array(YELLOW_TAGS, 10, TagReadB)) {
    // Do something for a yellow tag
} else if (is_tag_in_array(BLUE_TAGS, 7, TagReadB) {
    // Do something for a blue tag
} else {
    // Didn't match any color
}
...