簡體   English   中英

在圖的struct中聲明的函數指針,分配相同的函數

[英]Function pointer declared in struct for graph, assign same function

基本上我不能使這個邏輯模擬器起作用! 我制作了一個鄰接表,將所有門相互連接,然后為它們分配一個值,作為負責人的AdjList應該使用功能指針計算該值。 問題是它調用的唯一函數是And!​​(永遠不會調用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;
}

我認為您的代碼無法產生您所說的結果。 請看這里:

http://coliru.stacked-crooked.com/a/405b04c8d9113790-檢查此輸出

為什么要通過大小寫比較將字符串轉換為帶有strtoi的整數?

大小寫strtoi(“ NAND”):

  • 更好的方法是將strcmp或將每個字符串存儲在一個字符串中,或​​者將其存儲在一個查找表中,並執行“ ==相等相等”比較,這對於字符串來說是重載的。

考慮通過引用而不是值傳遞向量和對象,您可能期望對象返回一個值,但是由於通過值傳遞,您永遠看不到它們,這也避免了復制向量的開銷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM