Сокращение или устранение дублирующихся записей массива
Я хотел бы исключить или радикально сократить записи константного массива для поиска, который включает наборы констант или следующее состояние. Возможно, это очень просто сделать, я просто не знаю, какую структуру использовать. Я пишу встроенный C-код, где пытаюсь сделать все очень быстро, но некоторые из этих массивов становятся очень большими, поэтому мне нужно найти баланс между скоростью кода и пространством. У меня нет большого опыта встраиваемого кода, и у нас нет опыта в моей компании.
В качестве небольшого примера рассмотрим три флаговые переменные, которые определяют следующее состояние: fEnable, fDone и fFault. Допустим, я кодирую fEnable как бит 2, fDone как бит 1, а fFault как бит 0. Тогда у меня будет такая таблица, чтобы определить состояние:
const uint8_t NEXT_STATE[] = {
SEQ_SAME, // 000
SEQ_PREV, // 001
SEQ_PREV, // 010
SEQ_PREV, // 011
SEQ_SAME, // 100
SEQ_PREV, // 101
SEQ_NEXT, // 110
SEQ_PREV // 111
};
Мое следующее состояние определяется закодированным вводом:
p->state = NEXT_STATE[ p->encodedInput ];
У меня есть несколько таких константных массивов для моего кода, для временных констант и других значений (не только для следующего состояния).
Мой вопрос заключается в том, каков наилучший способ устранения избыточных записей в таблице поиска, такой как эта? Например, вы можете использовать сокращение логики и знать, что если fFault когда-либо установлен, вы хотите SEQ_PREV. Если нет, если fDone не установлен, вы хотите SEQ_SAME. Для (! FFault)(fDone)(fEnabled) = SEQ_PREV, (! FFault)(fDone)(! FEnabled) = SEQ_NEXT. Я могу как-то увидеть, как вы доберетесь с постоянной двоичной таблицей, но я не уверен, что это лучший способ сделать это.
В качестве примера таблицы намного большего размера рассмотрим эту (извините за форматирование здесь):
const enum PowerState_t PWR_TRANSITION_TABLE[16][PWR_NUM_STATES] =
{ // PWR_OFF PWR_T_ON PWR_ON PWR_T_OFF PWR_FAULT PWR_CRIT_FAULT
{PWR_FAULT, PWR_T_OFF, PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_CRIT_FAULT }, // 0000
{PWR_FAULT, PWR_T_ON, PWR_FAULT, PWR_T_ON, PWR_FAULT, PWR_CRIT_FAULT }, // 0001
{PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT }, // 0010
{PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT }, // 0011
{PWR_OFF, PWR_OFF, PWR_FAULT, PWR_OFF, PWR_OFF, PWR_OFF }, // 0100
{PWR_T_ON, PWR_T_ON, PWR_FAULT, PWR_T_ON, PWR_FAULT, PWR_CRIT_FAULT }, // 0101
{PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT }, // 0110
{PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT }, // 0111
{PWR_CRIT_FAULT, PWR_T_OFF, PWR_T_OFF, PWR_T_OFF, PWR_FAULT, PWR_CRIT_FAULT }, // 1000
{PWR_CRIT_FAULT, PWR_ON, PWR_ON, PWR_T_ON, PWR_FAULT, PWR_CRIT_FAULT }, // 1001
{PWR_CRIT_FAULT, PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT }, // 1010
{PWR_CRIT_FAULT, PWR_FAULT, PWR_FAULT, PWR_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT }, // 1011
{PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT }, // 1100
{PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT }, // 1101
{PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT }, // 1110
{PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT } // 1111
};
Заранее спасибо за помощь.