Получение одной строки таблицы истинности с непостоянным числом переменных

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

Вот пример таблицы истинности

Row| A | B | C |
 1 | T | T | T |
 2 | T | T | F |
 3 | T | F | T |
 4 | T | F | F |
 5 | F | T | T |
 6 | F | T | F |
 7 | F | F | T |
 8 | F | F | F |

Обратите внимание, что данная таблица истинности может иметь больше или меньше строк, чем эта таблица, поскольку количество возможных переменных может меняться.

Прототип функции может выглядеть так

getRow(int rowNum, bool boolArr[]);

Если бы эта функция была вызвана, например, как

getRow(3, boolArr[])

Ему нужно будет вернуть массив со следующими элементами

|1|0|1|    (or |T|F|T|)  

Трудность для меня возникает из-за того, что количество переменных может меняться, следовательно, увеличиваться или уменьшаться количество строк. Например, список переменных может быть A, B, C, D, E и F, а не просто A, B и C.

Я думаю, что лучшим решением было бы написать цикл, который считал до номера строки и существенно изменил элементы массива, как если бы он считался в двоичном формате. Так что

1st loop iteration, array elements are 0|0|...|0|1|
2nd loop iteration, array elements are 0|0|...|1|0|

Я не могу понять, как это сделать, и не могу найти решение в другом месте в Интернете. Извините за всю путаницу и спасибо за помощь


person FutureShocked    schedule 21.01.2015    source источник
comment
При чем тут сама формула? Является ли целью выяснить, какими будут отдельные назначения переменных для данной строки таблицы, или как проанализировать формулу для оценки?   -  person templatetypedef    schedule 21.01.2015
comment
@templatetypedef Конечная цель — проанализировать формулу с каждым возможным значением истинности для любого количества переменных. По сути, чтобы проверить каждую строку таблицы истинности, чтобы увидеть, удовлетворяет ли она формуле. Вот почему важно иметь возможность генерировать каждую строку таблицы истинности отдельно. Например, если a, b и c являются переменными, мне нужно проверить каждую комбинацию true и false для трех, чтобы увидеть, какие комбинации приводят к тому, что вся формула верна.   -  person FutureShocked    schedule 21.01.2015
comment
Пожалуйста, попробуйте улучшить формулировку проблемы. Вы упоминаете genTruth, не объясняя, что должна вычислять функция, а затем переходите к битовым сдвигам. Было бы полезно с вашим объяснением, если бы вы сначала четко изложили проблему, а затем объяснили свой подход.   -  person Pradhan    schedule 21.01.2015
comment
@Pradhan Если есть что-то, чему я быстро учусь на этом сайте, так это тому, как задавать эффективный вопрос. Мой отредактированный подход лучше?   -  person FutureShocked    schedule 21.01.2015
comment
Да, это намного лучше! Есть ли конкретная причина, по которой прототип должен быть getRow(rowNum, boolArr[]);? массивы в стиле C превращаются в указатели при использовании в качестве аргумента функции. Если вы знаете размер массива во время компиляции, гораздо проще работать с std::array . Если вам нужно определить размер во время выполнения, вы можете использовать std::vector и ваш прототип может быть getRow(rowNum, vector, numVars).   -  person Pradhan    schedule 21.01.2015
comment
@Pradhan Нет, это было просто предложение моего профессора. Я все еще приспосабливаюсь к векторам, так как начал их изучать несколько дней назад.   -  person FutureShocked    schedule 21.01.2015


Ответы (1)


Хорошо, теперь, когда вы переписали свой вопрос, чтобы он был намного яснее. Во-первых, getRow должен принимать дополнительный аргумент: количество битов. Строка 1 с 2 битами дает другой результат, чем строка 1 с 64 битами, поэтому нам нужен способ различать это. Во-вторых, как правило, в C++ все имеет нулевой индекс, поэтому я собираюсь сдвинуть вашу таблицу истинности на одну строку вниз, чтобы строка «0» возвращала все true.

Ключевым моментом здесь является понимание того, что номер строки в двоичном формате уже является тем, что вам нужно. Возьмем этот ряд (сдвинув 4 на 3):

3 | T | F | F |

3 в двоичном формате — это 011, инвертированное — {true, false, false} — именно то, что вам нужно. Мы можем выразить это с помощью побитового или в виде массива:

{!(3 | 0x4), !(3 | 0x2), !(3 | 0x1)}

Так что это просто вопрос записи в виде цикла:

void getRow(int rowNum, bool* arr, int nbits)
{
    int mask = 1 << (nbits - 1);
    for (int i = 0; i < nbits; ++i, mask >>= 1) {
        arr[i] = !(rowNum & mask);
    }
}
person Barry    schedule 21.01.2015
comment
Извините за это, я попытался немного уточнить, переименовав переменные в моем OP в буквы вместо цифр. Я не думаю, что это правильно, основываясь на том, что я мог понять на справочной странице cplusplus для набора битов. Мне кажется, что ваша версия функции возвращает всю таблицу истинности, но мне нужно иметь возможность генерировать ее по одной строке за раз. Первая строка таблицы истинности с двумя переменными будет [T|T], вторая — [T|F], третья — [F|T] и четвертая — [F|F]. Приношу свои извинения, если это звучит снисходительно, просто пытаюсь прояснить как можно больше. - person FutureShocked; 21.01.2015
comment
@FutureShocked Если вам нужна только таблица истинности, это просто переменная bits в моем ответе. Это будут значения в rowNum строке. - person Barry; 21.01.2015
comment
Это возвращает только одно логическое значение, не так ли? Даже не обращая внимания на то, что rowNum будет больше 8 для любого количества переменных больше 3, мне все равно нужна функция для возврата логического значения для каждой переменной в строке. - person FutureShocked; 21.01.2015
comment
@FutureShocked Хорошо, гораздо более ясный вопрос - я переписал свой ответ. - person Barry; 21.01.2015