2016-06-21 72 views
0

基本上我不能讓這個邏輯模擬器工作!我創建了一個相鄰列表,它將所有門相互連接,然後爲它們分配一個值,並且頭部的AdjList應該使用函數指針計算值。問題是,它調用的唯一功能是與!(XOR的Nand等。從來沒有所謂的) 具體點,其中指針被初始化函數指針在結構圖中聲明,分配相同的函數

struct AdjList 
{ 
    struct AdjListNode *head; 
    string GateName; 
    string OutputName; 
    bool result; 
    function <bool (vector <bool>)> ptrf; 

}; 

,並分別爲它們分配

 if(i < Gate_IO.size()) 
     { 
      ptrPos = Gate_IO[i].find_first_of(' '); 
      switch (strtoi ((Gate_IO[i].substr(0,ptrPos).c_str()))) 
      { 
       case strtoi("AND"): 
        { 
         VectorHeadPtr[i].ptrf = And; 
         break; 
        } 
       case strtoi("NAND"): 
        { 
         VectorHeadPtr[i].ptrf = Nand; 
         break; 
        } 
       case strtoi("OR"): 
        { 
         VectorHeadPtr[i].ptrf = Or; 
         break; 
        } 
       case strtoi("NOR"): 
        { 
         VectorHeadPtr[i].ptrf = Nor; 
         break; 
        } 
       case strtoi("XOR"): 
        { 
         VectorHeadPtr[i].ptrf = Xor; 
         break; 
        } 
       default: 
         break; 
      } 

然後函數CalcGateValue()它們被調用來執行程序!它似乎被識別並分配給VectorHeadPtr [i] .ptrf中的正確值,我試圖在那一點上做出決定,並進入該週期,但當我調用CalcGateValue()時調用的唯一函數是And!我錯過了什麼嗎? 下面是完整的代碼:

#include <iostream> 
#include <cstdlib> 
#include <string> 
#include <sstream> 
#include <vector> 
#include <algorithm> 
#include <functional> 
using namespace std; 
int compare(string a, string b) 
{ 
    int n = count(a.begin(), a.end(), 'I'); 
    int q = count(b.begin(), b.end(), 'I'); 
    return n > q; 
} 
constexpr unsigned int strtoi(const char* str, int h = 0) //string to int for switch cycle 
{ 
    return !str[h] ? 5381:(strtoi(str, h+1)*33)^str[h]; 
} 
     bool Xor(vector<bool> inputs) 
     { cout<<"Xor function called!"<<endl; 
      int counter = 0; 
      for (unsigned int i = 0;i < inputs.size(); i++) 
      { 
       if (inputs.at(i) == 1) 
       { 
        counter++; 
       } 
      } 
      if (counter % 2) //Xor gate gives output 1 if and odd number of 1 inputs is given 
      { 
       return 1; 
      } 
      else 
      { 
       return 0; 
      } 
     } 

     bool And(vector<bool> inputs) //static per richiamare la funzione dalla classe 
     { cout<<"And function called!"<<endl; 
      for (int i = 0; i < (inputs.size()-1); i++) 
       { 
        if(inputs.at(i) == 0) 
        { 
         return 0; 
        } 
       } 
      return 1; 
     } 
     bool Nand(vector<bool> inputs) 
     { cout<<"Nand function called!"<<endl; 
     return !And(inputs); 
     } 
     bool Or(vector<bool> inputs) 
     {cout<<"Or function called!"<<endl; 
      for (int i = 0; i < (inputs.size()-1); i++) 
      { 
       if (inputs.at(i) != inputs.at(i+1)) 
       { 
        return 1; 
       } 
      } 
      return inputs.at(0);//Any position it's ok because all nPoss are the same. 
     } 
     bool Nor(vector<bool> inputs) 
     { cout<<"Nor function called!"<<endl; 
      return !Or(inputs); 
     } 
/* 
* Adjacency list node 
*/ 
struct AdjListNode 
{ 
    int nPos; 
    bool gValue; 
    string name; 
    struct AdjListNode* next; 
}; 

/* 
* Adjacency list 
*/ 
struct AdjList 
{ 
    struct AdjListNode *head; 
    string GateName; 
    string OutputName; 
    bool result; 
    function <bool (vector <bool>)> ptrf; 

}; 

/** 
* Class Graph 
*/ 
class Graph 
{ 
    private: 
     int V; 
     int circInputs = 3; 
     int circOutputs = 2; 
     int circGates; 
     int PrimaryInputs = 0; 
     vector<string> ioPuts; 
     struct AdjList* VectorHeadPtr; 
    public: 
     Graph(vector<string> Gate_IO) 
     { 
      int ptrPos,cntr; 
      int cntrIO = 0; 
      int prevPrimaryInputs = 0; 
      bool flag_remove_duplicates = 0; 
      string GateToConnect; 
      circGates = Gate_IO.size(); 
      V=Gate_IO.size() + circInputs + circOutputs; //n°gates+input+output letti dal file 
      sort (Gate_IO.begin(), Gate_IO.end(), compare); 
      for (cntr = 0; cntr < (Gate_IO.size()-1) && (PrimaryInputs == prevPrimaryInputs); cntr++) 
      { 
       PrimaryInputs = count (Gate_IO[cntr+1].begin(), Gate_IO[cntr+1].end(), 'I'); 
       prevPrimaryInputs = count (Gate_IO[cntr].begin(), Gate_IO[cntr].end(), 'I'); 
      } 
      PrimaryInputs = cntr; //Here starts first N 
      for (int i = 0;i<Gate_IO.size();i++) 
      VectorHeadPtr = new AdjList [V]; 
      for (int i = 0; i < V; i++) 
      { 
       if(i < Gate_IO.size()) 
       { 
        ptrPos = Gate_IO[i].find_first_of(' '); 
        switch (strtoi ((Gate_IO[i].substr(0,ptrPos).c_str()))) 
        { 
         case strtoi("AND"): 
          { 
           VectorHeadPtr[i].ptrf = And; 
           break; 
          } 
         case strtoi("NAND"): 
          { 
           VectorHeadPtr[i].ptrf = Nand; 
           break; 
          } 
         case strtoi("OR"): 
          { 
           VectorHeadPtr[i].ptrf = Or; 
           break; 
          } 
         case strtoi("NOR"): 
          { 
           VectorHeadPtr[i].ptrf = Nor; 
           break; 
          } 
         case strtoi("XOR"): 
          { 
           VectorHeadPtr[i].ptrf = Xor; 
           break; 
          } 
         default: 
           break; 
        } 
        VectorHeadPtr[i].head = NULL; 
        stringstream ss; 
        ss << Gate_IO[i]; 
        for (string temp; ss >> temp;) 
        { 
         if ((temp.at(0)=='I') || (temp.at(0)=='O') && (temp!="OR")) 
         { 
          ioPuts.push_back(temp); 
         } 
         else if (temp.at(0) == 'U') 
         { 
          VectorHeadPtr[i].GateName=temp; 
         } 
        } 
        ptrPos = Gate_IO[i].find_last_of(' '); 
        VectorHeadPtr[i].OutputName = Gate_IO[i].substr(ptrPos); 
       } 
       else 
       { 
        if (flag_remove_duplicates == 0) 
         { 
          sort (ioPuts.begin(), ioPuts.end()); 
          ioPuts.erase (unique (ioPuts.begin(), ioPuts.end()), ioPuts.end()); 
          flag_remove_duplicates = 1; 
         } 
        VectorHeadPtr[i].head = NULL; 
        VectorHeadPtr[i].ptrf = NULL; 
        VectorHeadPtr[i].GateName = ioPuts[cntrIO]; 
        cntrIO++; 
       } 
      } 
      for (int i = 0; i < Gate_IO.size(); i++) 
      { 
       for(int j = 0; j < 2; j++) 
       { 
        ptrPos = Gate_IO[i].find_first_of(' ')+1; 
        Gate_IO[i].erase (0,ptrPos); 
       } 
       ptrPos = Gate_IO[i].find_last_of(' ')+1; 
       Gate_IO[i].erase(ptrPos); 
       stringstream ss; 
       ss << Gate_IO[i]; 
       ss >> GateToConnect; 
       for (string temp; ss >> temp;) 
       { 
        addEdge(GateToConnect,temp); 
       } 
      } 
     } 
     /** 
     * Creates new adjacency list node for addEdge function 
     */ 
     AdjListNode* newAdjListNode(int nPos, string Name) 
     { 
      AdjListNode* newNode = new AdjListNode; 
      newNode->nPos = nPos; 
      newNode->name = Name; 
      newNode->next = NULL; 
      return newNode; 
     } 
     /** 
     * Add edge to graph 
     */ 
     void addEdge(string source, string destination) 
     { 
      int from, to; 
      for (int i = 0; i < V; ++i) 
      { 
       if ((source == VectorHeadPtr[i].GateName) || (source == VectorHeadPtr[i].OutputName)) 
       { 
        from = i; 
       } 
       else if ((destination == VectorHeadPtr[i].GateName) || (destination == VectorHeadPtr[i].OutputName)) 
       { 
        to = i; 
       } 
      } 
      AdjListNode* newNode = newAdjListNode(to, destination); 
      newNode->next = VectorHeadPtr[from].head; 
      VectorHeadPtr[from].head = newNode; 
     } 
     /* 
     * Print the graph 
     */ 
     void printGraph() 
     { 
      for (int i = 0; i < circGates; i++)//meno ooutput+input 
      { 
       AdjListNode* Ptr = VectorHeadPtr[i].head; 
       cout<<endl<<"Gate connections for "<<VectorHeadPtr[i].GateName; 
       while (Ptr) 
       { 
        cout <<"-> "<< Ptr->name; 
        Ptr = Ptr->next; 
       } 
       cout<<" Output name is:"<<VectorHeadPtr[i].OutputName<<endl; 
      } 
     } 
     void calcGateVal() 
     { 
      vector<bool> Val={0, 1, 0}; 
      vector<bool> Op; 
      for (int i = 0; i < circOutputs; i++) 
      { 
       ioPuts.pop_back(); 
      } 
      for (int i = 0; i < circGates; i++) 
      { 
       AdjListNode* Ptr = VectorHeadPtr[i].head; 
       while (Ptr) 
       { 
        if (Ptr->name.at(0) == 'I') 
        { 
         for (int j = 0; j < ioPuts.size(); j++) 
         { 
          if (Ptr->name == ioPuts[j]) 
          { 
           Ptr->gValue = Val[j]; 
          } 
         } 
        } 
        Ptr = Ptr->next; 
       } 
      } 
      for (int i = 0; i < PrimaryInputs; i++) 
      { 
       AdjListNode* Ptr = VectorHeadPtr[i].head; 
       while (Ptr) 
       { 
        Op.push_back(Ptr->gValue); 
        Ptr = Ptr->next; 
       } 
       VectorHeadPtr[i].result = VectorHeadPtr[i].ptrf(Op); 
       cout<<"Gate Value is: "<<VectorHeadPtr[i].result<<" OutputName: "<<VectorHeadPtr[i].OutputName<<" GateName: "<<VectorHeadPtr[i].GateName<<endl; 
       Op.clear(); 
      } 
      for (int i = PrimaryInputs; i < V; i++) 
      { 
       AdjListNode* Ptr = VectorHeadPtr[i].head; 
       while (Ptr) 
       { 
         for (int j = 0; j < PrimaryInputs; j++) 
         { 
          if (Ptr->name == VectorHeadPtr[j].OutputName) 
          { 
           Ptr->gValue = VectorHeadPtr[j].result; 
          } 
         } 
        Ptr = Ptr->next; 
       } 
      } 
      for (int i = PrimaryInputs; i < circGates; i++) 
      { 
       AdjListNode* Ptr = VectorHeadPtr[i].head; 
       while (Ptr) 
       { 
        Op.push_back(Ptr->gValue); 
        Ptr = Ptr->next; 
       } 
       VectorHeadPtr[i].result = VectorHeadPtr->ptrf(Op); 
       Op.clear(); 
      } 
     } 
     void displayOutput() 
     { cout<<endl; 
      for (int i = 0; i < circGates; i++) 
      { 
       cout<<"Value of outputs are ("<<VectorHeadPtr[i].GateName<<") "<<VectorHeadPtr[i].OutputName<<": "<<VectorHeadPtr[i].result<<endl; 
      } 
     } 
}; 
/* 
* Main 
*/ 
int main() 
{ 
    vector<string> G_d; 
    G_d.push_back("AND 2 U0 I0 I1 N0"); 
    G_d.push_back("XOR 2 U1 N0 I2 O0"); 
    G_d.push_back("AND 2 U2 N0 I2 N1"); 
    G_d.push_back("AND 2 U3 I0 I1 N2"); 
    G_d.push_back("OR 2 U4 N1 N2 O1"); 
    Graph gh(G_d); 
    gh.calcGateVal(); 
    gh.displayOutput(); 
    gh.printGraph(); 

    // print the adjacency list representation of the above graph 

    return 0; 
} 

回答

0

我覺得你的代碼不會產生你說什麼它產生。請看這裏:

http://coliru.stacked-crooked.com/a/405b04c8d9113790 - Check the output of this

爲什麼要將字符串轉換爲strtoi與您的案例比較的整數? :

case strtoi("NAND"):

  • 一個更好的辦法是STRCMP或存儲每個字符串中的可能查找表,做一個「==」等於等於其超載字符串比較。

考慮通過您的載體,並通過引用而不是值對象周圍,你可能會希望在你的對象一個回報,但因爲你按值傳遞你永遠看不到他們,這也避免了製作的副本的開銷向量。

+0

感謝您的巡演答案!我重新上傳了代碼,以便輸出更容易理解!用鉤子表表達什麼意思?我試圖調試該區域,它似乎工作正常!我使用stroi因爲它似乎對我來說比其他系列更容易理解,如果 – Idan1109

+0

查找表,而不是掛鉤。例如:std :: unordered_map )>> lookuptable = {{「AND」,And},{「NAND」,Nand}}; - 一旦你用這種方式聲明它,你設置VectorHeadPtr [i] .ptrf = lookuptable [「AND」] - 這會給你相應的功能「AND」 –

+0

謝謝Samer Tufail看起來很容易查找表,但我不能做它在VectorHeadPtr行[i] .ptrf = lookuptable [「AND」];它給了我錯誤: – Idan1109