Я пытался исправить ошибку, и я очень запутался, кажется, что всякий раз, когда я использую 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;
}