⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gates.cpp

📁 C++&datastructure书籍源码,以前外教提供现在与大家共享
💻 CPP
字号:
#include <iostream>
#include <sstream>
using namespace std;
#include "gates.h"
#include "wires.h"
#include "strutils.h"
#include "linkset.h"
#include "simplemap.h"

WireFactory * Gate::ourWireFactory = new WireFactory();

Wire* Gate::WireByNumber(int num)
{   Wire * w = ourWireFactory->GetWire(num);
    return w;
}

ostream& operator << (ostream& out, const Gate& g)
{
    out << g.tostring();
    return out;
}

void Connect(Wire * w1, Wire * w2)
{
    if (w1 != 0 && w2 != 0)
    {   Connector * con = new Connector(w1,w2);
    }
}

int Inverter::ourCount = 0;

Inverter::Inverter(Wire* in, Wire* out, const string& name)
  : myIn(in),
    myOut(out),
    myName(name),
    myNumber(ourCount)
{
    ourCount++;
    in->AddGate(this);
}
 
Inverter::Inverter(const string& name)
  : myIn(ourWireFactory->MakeWire(name)),
    myOut(ourWireFactory->MakeWire(name)),
    myName(name),
    myNumber(ourCount)
{
    ourCount++;
    myIn->AddGate(this);
}
 
void Inverter::Act( )
{
    myOut->SetSignal(! myIn->GetSignal());
}
 
string Inverter::tostring() const
{
    return "inv (" + ::tostring(myNumber) + ") " + myName;
}

Gate * Inverter::clone()
{
    return new Inverter(myName);
}

string Inverter::deepString() const
{
    ostringstream out;
    out << *this << "\n\tin" << *myIn << "\tout" << *myOut;
    out << "\n----";
    return out.str();
}

Connector::Connector(Wire * in, Wire * out)
  : myIn(in), myOut(out)
{
   in->AddGate(this); 
}

void Connector::Act()
{
    myOut->SetSignal(myIn->GetSignal());
}

string Connector::tostring() const
{
    return "connector " + myIn->tostring() + " to " + myOut->tostring();
}

Gate * Connector::clone()
{
    return new Connector(myIn,myOut);
}

NMGate::NMGate(int number, const string& name)
  : myNumber(number),
    myName(name)
{

}

void NMGate::Init(const tvector<Wire *>& in, const tvector<Wire *>& out)
{
   myIns = in;
   myOuts = out;
   int k;
   for(k=0; k < in.size(); k++)
   {
       in[k]->AddGate(this);
   }
}

string NMGate::deepString() const
{
   ostringstream out;
   out << *this << "\n\tin ";
   int k;
   for(k=0; k < myIns.size(); k++)
   {   out << *myIns[k] << " ";
   }
   out << "\tout ";
   for(k=0; k < myOuts.size(); k++)
   {   out << *myOuts[k] << " ";
   }
   out << "\n----";
   return out.str();
}


int AndGate::ourCount = 0;

AndGate::AndGate(Wire * in, Wire* in2, Wire * out, const string& name)
  : NMGate(ourCount, name)
{
    tvector<Wire *> ins(2), outs(1);
    ins[0] = in;
    ins[1] = in2;
    outs[0] = out;
    NMGate::Init(ins,outs);
    ourCount++;
}

AndGate::AndGate(const string& name)
  : NMGate(ourCount,name)
{
    tvector<Wire *> ins(2), outs(1);
    ins[0] = ourWireFactory->MakeWire(myName);
    ins[1] = ourWireFactory->MakeWire(myName);
    outs[0] = ourWireFactory->MakeWire(myName);    
    NMGate::Init(ins,outs);
    ourCount++;
}

Gate * AndGate::clone()
{
    return new AndGate(myName);
}


void AndGate::Act( )
{
    myOuts[0]->SetSignal(myIns[0]->GetSignal() && myIns[1]->GetSignal());
}

string AndGate::tostring() const
{
    return "and (" + ::tostring(myNumber) + ") " + myName;
}

int OrGate::ourCount = 0;

OrGate::OrGate(Wire * in, Wire* in2, Wire * out, const string& name)
  : NMGate(ourCount, name)
{
    tvector<Wire *> ins(2), outs(1);
    ins[0] = in;
    ins[1] = in2;
    outs[0] = out;
    NMGate::Init(ins,outs);
    ourCount++;
}

OrGate::OrGate(const string& name)
  : NMGate(ourCount,name)
{
    tvector<Wire *> ins(2), outs(1);
    ins[0] = ourWireFactory->MakeWire(myName);
    ins[1] = ourWireFactory->MakeWire(myName);
    outs[0] = ourWireFactory->MakeWire(myName);    
    NMGate::Init(ins,outs);
    ourCount++;
}


void OrGate::Act( )
{
    myOuts[0]->SetSignal(myIns[0]->GetSignal() || myIns[1]->GetSignal());
}

string OrGate::tostring() const
{
    return "or (" + ::tostring(myNumber) + ") " + myName;
}

Gate * OrGate::clone()
{
    return new OrGate(myName);
}

CompositeGate::CompositeGate()
  : NMGate(0, "composite")
{

}

string CompositeGate::tostring() const
{
    ostringstream result;
    result << "composite: " << myGates.size() << " gates, ";
    result << InCount() << " in wires, " << OutCount() << " out wires";
    return result.str();
}

string CompositeGate::deepString() const
{
    ostringstream out;
    int k;
    out << *this << "\nall-in\t";
    for(k=0; k < InCount(); k++)
    {   out << *InWire(k) << " ";
    }
    out << "\nall-out\t";
    for(k=0; k < OutCount(); k++)
    {   out << *OutWire(k) << " ";
    }
    out << endl;
    for(k=0; k < myGates.size(); k++)
    {   out << "\t" << myGates[k]->deepString() << endl;
    }
    out << "------";
    return out.str();
}

void CompositeGate::Act()
{
  // nothing to do
}

void CompositeGate::AddIn(Wire * w)
{
    myIns.push_back(w);
    w->AddGate(this);
}

void CompositeGate::AddOut(Wire * w)
{
    myOuts.push_back(w);
}

void CompositeGate::AddGate(Gate * g)
{
    myGates.push_back(g);
}

int CompositeGate::CountWires() const
{
    LinkSet<Wire *> wires;
    int j,k, gCount = myGates.size();
    for(j=0; j < gCount; j++)
    {   Gate * g = myGates[j];
        for(k=0; k < g->InCount(); k++)
        {   wires.insert(g->InWire(k));
        }
        for(k=0; k < g->OutCount(); k++)
        {   wires.insert(g->OutWire(k));
        }
    }
    for(j=0; j < InCount(); j++)
    {   wires.insert(InWire(j));
    }
    for(j=0; j < OutCount(); j++)
    {   wires.insert(OutWire(j));
    }
    return wires.size();
}

Gate * CompositeGate::clone()
{
    LinkSet<Wire *> wires;
    CompositeGate * copy = new CompositeGate();
    SimpleMap<Wire *, Wire *> map;
    int j,k, gCount = myGates.size();
    
    for(j=0; j < gCount; j++)
    {   Gate * g = myGates[j]->clone();
    
        for(k=0; k < myGates[j]->InCount(); k++)
        {   Wire * w = myGates[j]->InWire(k);
            if (! wires.contains(w))
            {   wires.insert(w);
                map.insert(w,g->InWire(k));
            }
            else
            {   Connect(map.getValue(w),g->InWire(k));
            } 
        }
        for(k=0; k < myGates[j]->OutCount();k++)
        {   Wire * w = myGates[j]->OutWire(k);
            if (! wires.contains(w))
            {   wires.insert(w);
                map.insert(w,g->OutWire(k));
            }
            else
            {   Connect(g->OutWire(k),map.getValue(w));
            }
        }
        copy->AddGate(g);
    }
    for(j=0; j < InCount(); j++)
    {   Wire * w = InWire(j);
        if (! wires.contains(w))
        {   wires.insert(w);
            map.insert(w,ourWireFactory->MakeWire("clone"+w->tostring()));
        }
    }
    for(j=0; j < OutCount(); j++)
    {   Wire * w = OutWire(j);
        if (! wires.contains(w))
        {   wires.insert(w);
            map.insert(w,ourWireFactory->MakeWire("clone"+w->tostring()));
        }
    }
    //cout << "found " << wires.size() << " different wires " << endl;  
    for(k=0; k < InCount(); k++)
    {  if (! wires.contains(InWire(k))) 
       { cout << InWire(k)->tostring() << " not found" << endl;
         continue;
       }
       copy->AddIn(map.getValue(InWire(k)));
    }
    for(k=0; k < OutCount(); k++)
    {   copy->AddOut(map.getValue(OutWire(k)));
    }
    
    LinkSetIterator<Wire *> wit(wires);
    for(wit.Init(); wit.HasMore(); wit.Next())
    {   Wire * from = wit.Current();
        ConnectorIterator conit(from);
        for(conit.Init(); conit.HasMore(); conit.Next())
        {   Wire * to = conit.Current()->OutWire(0);
            if (wires.contains(to))
            {   Connect(map.getValue(from),map.getValue(to));
            }
        }
    }
    return copy;
}


void GateTester::Test(Gate * gate)
{
    int inputs = gate->InCount();
    int outputs = gate->OutCount();
    int limit = 1 << inputs; // 2^# inputs
    int j,k;
    cout << "testing " << gate->tostring() << endl;
    cout << "-----" << endl;
    for(k=0; k < limit; k++)
    {   for(j=0; j < inputs; j++)
        {   if ( ((k >> j) & 1) == 1)
            {   gate->InWire(j)->SetSignal(true);
                cout << "1 ";
            }
            else
            {   gate->InWire(j)->SetSignal(false);
                cout << "0 ";
            }
        }
        cout << "\t : \t";
        for(j=0; j < outputs;j++)
        {   cout << (gate->OutWire(j)->GetSignal() ? "1 " : "0 ");
        }
        cout << endl;
    }    
    cout << "------" << endl;
}

Probe::Probe(Wire * w)
  : myWire(w)
{
    myWire->AddGate(this);
}

void Probe::Act()
{
    cout << *myWire << "\t signal= " << myWire->GetSignal() << endl;
}
string Probe::tostring() const
{
    return "probe " + myWire->tostring();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -