Лучший набор данных для таблицы истинности для вычисления и уменьшения суммы произведений в C#

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

string[][] truthTable = new string[8][];
            truthTable[0] = new string[2] { "1" , "000"};
            truthTable[1] = new string[2] { "0", "001" };
            truthTable[2] = new string[2] { "0", "010" };
            truthTable[3] = new string[2] { "0", "011" };
            truthTable[4] = new string[2] { "0", "100" };
            truthTable[5] = new string[2] { "1", "101" };
            truthTable[6] = new string[2] { "1", "110" };
            truthTable[7] = new string[2] { "1", "111" };





            for (int i = 0; i < truthTable.Length; i++)
            {
                // print out strings  that have "1 as first element"
                if (truthTable[i].GetValue(i) == "1" )

                {
                    Console.WriteLine(truthTable[i]);

                }

            }

то, что я хочу сделать прямо сейчас, это распечатать массивы, у которых есть «1» в качестве первого элемента. вывод консоли должен быть чем-то вроде «1» «000» для первого массива, например, и он должен печатать только три других массива, которые также имеют «1». но сейчас он выдает ошибку «за пределами» и ничего не печатает.

Это хороший способ начать работу с таблицей истинности для вычисления суммы произведений или есть лучший способ реализовать ее на С#?


person Ventus    schedule 03.12.2019    source источник
comment
должно быть if (truthTable[i].GetValue(0) == "1" . У вас есть i в GetValue, что будет за пределами, когда я › 0   -  person    schedule 03.12.2019
comment
он решает проблему выхода за пределы, но все, что он печатает, это System.String[] 4 раза, что лучше, чем то, что у меня было раньше, но как мне распечатать 000 101 и т. д.?   -  person Ventus    schedule 03.12.2019
comment
Console.WriteLine(truthTable[i][1]); печатает элемент с индексом 1 массива i. Реализация по умолчанию ToString() для объектов просто выводит имя типа, если оно не переопределено. Примитивные типы, такие как строки в массиве, выводят свое фактическое значение в виде строки.   -  person    schedule 03.12.2019
comment
Спасибо большое! это работает, но, по вашему мнению, это хороший способ реализовать таблицу истинности? если вы не знаете, это нормально.   -  person Ventus    schedule 03.12.2019
comment
Это зависит от вашего варианта использования, так как они могут быть довольно сложными. Как уже упоминалось в другом плакате, Dictionary или HashSet могут быть лучшим решением. Если вы хотите углубиться в суть, ознакомьтесь с этой реализацией TruthTable.   -  person    schedule 03.12.2019


Ответы (1)


Одной простой реализацией было бы использование Dictionary<string, string> вместо этого. Ключ string будет содержать ваши три значения переменных, а второе значение string будет содержать соответствующее значение истинности:

var truthTable = new Dictionary<string, string>
{
    { "000", "1" },
    { "001", "0" },
    { "010", "0" },
    { "011", "0" },
    { "100", "0" },
    { "101", "1" },
    { "110", "1" },
    { "111", "1" },
};

foreach (var keyValue in truthTable)
{
    // print out strings that have value of "1"
    if (keyValue.Value == "1")
    {
        Console.WriteLine(keyValue.Key);
    }
}

Хотя, возможно, это больше соответствует интересующей области, вы можете рассмотреть возможность использования Tuple из bool вместо string для ключа переменных и bool вместо string для значения:

var truthTable = new Dictionary<Tuple<bool, bool, bool>, bool>
{
    { new Tuple<bool, bool, bool>(false, true, false), true },
    { new Tuple<bool, bool, bool>(false, true, true), false },
    { new Tuple<bool, bool, bool>(false, false, false), false },
    { new Tuple<bool, bool, bool>(false, false, true), false },
    { new Tuple<bool, bool, bool>(true, true, false), false },
    { new Tuple<bool, bool, bool>(true, true, true), true },
    { new Tuple<bool, bool, bool>(true, false, false), true },
    { new Tuple<bool, bool, bool>(true, false, true), true },
};

foreach (var keyValue in truthTable)
{
    // print out strings that have true value
    if (keyValue.Value)
    {
        Console.WriteLine(keyValue.Key);
    }
}

Обновление: использование Linq для Dictionary

Вы можете приблизительно аппроксимировать Dictionary как List из KeyValuePair кортежей. Это означает, что вы можете использовать все функции Linq, доступные любому Collection -- например, приведенный выше цикл foreach может использовать метод расширения Where Linq и быть упрощен до следующего:

// print out strings that have true value
var trueKeyValuesList = truthTable.Where(kv => kv.Value).ToList();
foreach (var keyValue in trueKeyValuesList)
{
    Console.WriteLine(keyValue.Key);
}

В этом примере trueKeyValuesList это просто -- List<KeyValuePair<Tuple<bool, bool, bool>, bool>> (I ‹3 var :P ). Если вам просто нужен список значений Tuple, вы можете использовать метод Select Linq (который ведет себя аналогично map Python) вместе с Where:

// print out strings that have true value
var trueValueKeys = truthTable
    .Where(kv => kv.Value)
    .Select(kv => kv.Key)
    .ToList();
foreach (var boolTuple in trueValueKeys)
{
    Console.WriteLine(boolTuple);
}
person Bondolin    schedule 03.12.2019
comment
Эй, Бондолин, извините за поздний ответ, но это работает очень хорошо! вопрос, однако, я хочу начать выполнять логические операции со всеми кортежами, которые печатаются в цикле foreach. я думаю, что помещение их в новый список, а затем разделение кортежей позволит мне сделать это. но как добавить их в список? - person Ventus; 04.12.2019
comment
Спасибо за обновление, я попробую это. И просто хочу отметить, что основная причина, по которой я это делаю, - это возможность уменьшить сумму произведений таблицы истинности. если у вас есть какие-либо советы по этому поводу, я ценю это. еще раз спасибо за вашу помощь! - person Ventus; 04.12.2019
comment
Итак, я последовал вашему совету, и пока все довольно хорошо, но я столкнулся с препятствием. я пытаюсь уменьшить дубликаты в trueKeyList, выполнив var reduced1 = trueKeyList.Distinct().ToList();, но не удаляя ни одного из дубликатов. любая помощь с этим? кстати, я использую строковые кортежи, что-то вроде комбинации вашего первого и второго вариантов. - person Ventus; 04.12.2019
comment
Что ж, в тот момент, когда вы вызываете Distinct, trueKeyList — это всего лишь List строковых кортежей; которые, конечно, все будут другими, как они были с самого начала, так что я немного не уверен, что вы пытаетесь получить там? - person Bondolin; 04.12.2019
comment
вот пример кортежей, которые у меня есть {new Tuple <string,string,string>("A","!B","!C"),true },{new Tuple <string,string,string>("A","!B","C"),true },, когда мы добавим их в список и распечатаем их, будет два As в списке и два! B в списке, я хочу удалить дубликаты, чтобы только 1 A и 1 !B остается. Это возможно? - person Ventus; 04.12.2019
comment
Хм, не уверен. Я думаю, что на данный момент это может быть достаточным основанием для отдельного вопроса. - person Bondolin; 04.12.2019