std :: cout остановка программы - PullRequest
0 голосов
/ 01 августа 2020

Я пытался исправить ошибку, и я очень запутался, кажется, что всякий раз, когда я использую std::cout, программа зависает. Я понятия не имею, почему это происходит, и если кто-то из вас знает, почему мне хотелось бы знать.

вот мой исходный код для справки (std::cout находится внизу в основной функции ):

#include <iostream>
#include <vector>
#include <unordered_map>
#include <exception>
#include <string>
#include <fstream>

/*
template<
    typename T
>
std::ostream& operator<< (std::ostream& stream, std::vector<T> vec)
{
    for (int i = 0; i < vec.size() - 1; ++i)
    {
        stream << vec[i] << " ";
    }
    stream << vec.back();
    return stream;
}
*/


class gate
{
public:
    std::unordered_map<std::string, int> m_inputs;
    std::unordered_map<std::string, int> m_outputs;
    virtual std::vector<bool> calculate(const std::vector<bool>& inputs) = 0;
    gate(const std::unordered_map<std::string, int>& inputs, const std::unordered_map<std::string, int>& outputs) :
        m_inputs(inputs),
        m_outputs(outputs)
    {}
};

class elementary_gate : public gate
{
private:
    std::unordered_map<std::vector<bool>, std::vector<bool>> m_truth_table;
public:
    elementary_gate(const std::unordered_map<std::vector<bool>, std::vector<bool>>& truth_table,
        const std::unordered_map<std::string, int>& inputs,
        const std::unordered_map<std::string, int>& outputs
    ) :
        gate(inputs, outputs),
        m_truth_table(truth_table)
    {}
    std::vector<bool> calculate(const std::vector<bool>& inputs) override
    {
        return m_truth_table[inputs];
    }
};

class gate_reference
{
private:
    gate* m_gate;
    std::vector<int> m_input_connection_ids;
    std::vector<int> m_output_connection_ids;
public:
    gate_reference(gate* gate_ref, const std::vector<int>& input_connection_ids, const std::vector<int>& output_connection_ids) :
        m_gate(gate_ref),
        m_input_connection_ids(input_connection_ids),
        m_output_connection_ids(output_connection_ids)
    {}
    std::vector<bool> calculate(const std::vector<bool>& inputs)
    {
        return m_gate->calculate(inputs);
    }
    std::vector<int> get_input_connection_ids()
    {
        return m_input_connection_ids;
    }
    void set_output_connection_ids(const std::vector<bool>& output_vector, std::vector<bool>& connection_values)
    {
        for (int i = 0; i < output_vector.size(); ++i)
        {
            connection_values[m_output_connection_ids[i]] = output_vector[i];
        }
    }
};

class compound_gate : public gate
{
private:
    std::vector<gate_reference> m_gates;
    std::vector<int> m_output_connection_ids;
    int connection_count;
    int input_count;
public:
    std::vector<bool> calculate(const std::vector<bool>& inputs) override
    {
        if (inputs.size() != input_count)
        {
            throw std::length_error("incorrect input size for logic gate");
        }
        std::vector<bool> connection_values(connection_count);
        for (int i = 0; i < input_count; ++i)
        {
            connection_values[i] = inputs[i];
        }
        for (gate_reference gate_ref : m_gates)
        {
            std::vector<int> input_ids = gate_ref.get_input_connection_ids();
            std::vector<bool> input_vector = construct_io_vector(input_ids, connection_values);
            std::vector<bool> output_vector = gate_ref.calculate(input_vector);
            gate_ref.set_output_connection_ids(output_vector, connection_values);
        }
        return construct_io_vector(m_output_connection_ids, connection_values);
    }
private:
    std::vector<bool> construct_io_vector(const std::vector<int>& connection_ids, const std::vector<bool>& connection_values)
    {
        std::vector<bool> input_vector;
        for (int connection_id : connection_ids)
        {
            input_vector.push_back(connection_values[connection_id]);
        }
        return input_vector;
    }
};

std::vector<bool> get_vector_from_int(int num, int pad_length)
{
    std::vector<bool> bool_vec;
    while (num)
    {
        if (num % 2)
        {
            bool_vec.push_back(true);
        }
        else
        {
            bool_vec.push_back(false);
        }
        num >>= 1;
    }
    while (bool_vec.size() < pad_length)
    {
        bool_vec.push_back(false);
    }
    std::reverse(bool_vec.begin(), bool_vec.end());
    return bool_vec;
}

class gates
{
public:
    static std::unordered_map<std::string, elementary_gate*> gate_list;
};

std::unordered_map<std::string, elementary_gate*> gates::gate_list;

gate* load_elementary_gate(const std::string& filename)
{
    std::ifstream file(filename);
    std::string gate_name = filename.substr(0, filename.find('.'));
    int input_count;
    file >> input_count;
    std::unordered_map<std::string, int> inputs;
    for (int i = 0; i < input_count; ++i)
    {
        std::string input_name;
        file >> input_name;
        inputs.insert(std::make_pair(input_name, i));
    }
    int output_count;
    file >> output_count;
    std::unordered_map<std::string, int> outputs;
    for (int i = 0; i < output_count; ++i)
    {
        std::string output_name;
        file >> output_name;
        outputs.insert(std::make_pair(output_name, i));
    }
    int table_rows = 1 << input_count;
    std::unordered_map<std::vector<bool>, std::vector<bool>> truth_table;
    for (int i = 0; i < table_rows; ++i)
    {
        std::vector<bool> input_vector = get_vector_from_int(i, input_count);
        std::vector<bool> output_vector(output_count);
        for (int i = 0; i < output_count; ++i)
        {
            int val;
            file >> val;
            output_vector[i] = val;
        }
        truth_table.insert(std::make_pair(input_vector, output_vector));
    }
    elementary_gate* gate = new elementary_gate(truth_table, inputs, outputs);
    gates::gate_list.insert(std::make_pair(gate_name, gate));
    return gate;
}

gate* extract_gate_type(std::string& raw_gate)
{
    std::string gate_name = raw_gate.substr(0, raw_gate.find('('));
    raw_gate = raw_gate.substr(raw_gate.find('(') + 1, raw_gate.size() - raw_gate.find('(')- 2);
    return gates::gate_list[gate_name];
}

std::vector<std::string> split_string(std::string str, char delim)
{
    std::vector<std::string> split;
    bool new_str = true;
    for (char c : str)
    {
        if (new_str)
        {
            split.emplace_back("");
        }
        if (c == delim)
        {
            new_str = true;
        }
        else
        {
            if (c != ' ')
            {
                new_str = false;
                split.back() += c;
            }
        }
    }
    return split;
}

gate* load_circuit(const std::string& filename)
{
    std::ifstream file(filename);
    std::string gate_name = filename.substr(0, filename.find('.'));
    int input_count;
    file >> input_count;
    std::unordered_map<std::string, int> inputs;
    for (int i = 0; i < input_count; ++i)
    {
        std::string input_name;
        file >> input_name;
        inputs.insert(std::make_pair(input_name, i));
    }
    int output_count;
    file >> output_count;
    std::unordered_map<std::string, int> outputs;
    for (int i = 0; i < output_count; ++i)
    {
        std::string output_name;
        file >> output_name;
        outputs.insert(std::make_pair(output_name, i));
    }
    std::vector<gate*> gates;
    std::vector<std::string> sub_gates_raw;
    while (!file.eof())
    {
        std::string gate_str;
        char c = ' ';
        while (c != ')')
        {
            file >> c;
            gate_str += c;
        }
        std::cout << gate_str.size() << std::endl;
        if (gate_str.size() < 1)
        {
            continue;
        }
        gates.push_back(extract_gate_type(gate_str));
        sub_gates_raw.push_back(gate_str);
    }
    std::vector<std::vector<std::string>> io_split;
    for (std::string str : sub_gates_raw)
    {
        io_split.push_back(split_string(str, ','));
    }
    std::vector<std::vector<std::pair<std::string, std::string>>> gate_io_split;
    for (std::vector<std::string> gate_strs : io_split)
    {
        std::vector<std::pair<std::string, std::string>> gate_strs_lr_split;
        for (std::string io_str : gate_strs)
        {
            std::vector<std::string> gate_str_lr_split = split_string(io_str, '=');
            gate_strs_lr_split.push_back(std::make_pair(gate_str_lr_split[0], gate_str_lr_split[1]));
        }
        gate_io_split.push_back(gate_strs_lr_split);
    }
    std::unordered_map<std::string, int> connection_list;
    for (std::vector<std::pair<std::string, std::string>> gate_strs : gate_io_split)
    {
        for (std::pair<std::string, std::string> connection : gate_strs)
        {
            connection_list.insert(std::make_pair(connection.first, connection_list.size() - 1));
        }
    }
    for (std::pair<std::string, int> input : inputs)
    {
        inputs.insert_or_assign(input.first, connection_list[input.first]);
    }
    for (std::pair<std::string, int> output : outputs)
    {
        outputs.insert_or_assign(output.first, connection_list[output.first]);
    }
    std::vector<std::vector<std::pair<int, int>>> gates_connection_indexes;
    std::vector<std::vector<bool>> is_input;
    for (int i = 0; i < gate_io_split.size(); ++i)
    {
        std::vector<std::pair<std::string, std::string>> gate_connection_indexes_str = gate_io_split[i];
        std::vector<std::pair<int, int>> gate_connection_indexes;
        std::vector<bool> gate_connections;
        for (std::pair<std::string, std::string> gate_connection_index_str : gate_connection_indexes_str)
        {
            gate_connections.push_back(gates[i]->m_inputs.count(gate_connection_index_str.first));
            std::pair<int, int> connnection_indexes = std::make_pair(connection_list[gate_connection_index_str.first], connection_list[gate_connection_index_str.second]);
            gate_connection_indexes.push_back(connnection_indexes);
        }
        is_input.push_back(gate_connections);
        gates_connection_indexes.push_back(gate_connection_indexes);
    }
    std::vector<gate_reference> gate_references;
    for (int i = 0; i < gates_connection_indexes.size(); ++i)
    {

    }
    return nullptr;
}

int main(void)
{
    std::cout << "hello";
    //load_elementary_gate("nand.gate");
    //load_circuit("not.circuit");
    //load_circuit("or.circuit");
    return 0;
}
...