图算法应用

来源:互联网 发布:电脑超频软件 编辑:程序博客网 时间:2024/05/01 20:06

给了A、B两个单词和一个单词集合Dict,每个的长度都相同。我们希望通过若干次操作把单词A变成单词B,每次操作可以改变单词中的一个字母,同时,新产生的单词必须是在给定的单词集合Dict中。求所有行得通步数最少的修改方法。    举个例子如下: Given:    A = "hit"    B = "cog"    Dict = ["hot","dot","dog","lot","log"] Return  [    ["hit","hot","dot","dog","cog"],    ["hit","hot","lot","log","cog"]  ]     即把字符串A = "hit"转变成字符串B = "cog",有以下两种可能: "hit" -> "hot" ->  "dot" ->  "dog" -> "cog"; "hit" ->  "hot" ->  "lot" ->  "log"  ->"cog"。


#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
using std::endl;
using std::string;
using std::vector;


/**
 * search  graph
 *
 */
class Graph{
private:
    /**
     * graph node
     */
    class Node{
    public:
        vector<Node*> nextNList;
        string data;
        Node(string data){
            this->data = data;
            nextNList.clear();
        }
        vector<vector<Node*> > roads;
    };


    vector<Node*> allNode;
    Node* ghead;
    Node* gend;


    int nodeLen;
    int changeStep;
public:
    Graph(string start, string end, int len, int step) {
        ghead = new Node(start);
        gend = new Node(end);
        allNode.push_back(ghead);
        allNode.push_back(gend);
        nodeLen = len;
        changeStep = step;
    }
    ~Graph(){
        delete ghead, gend;
    }


    void addNode(string data){
        Node* n = new Node(data);


        addToGraph(n);
    }


    void display(){
        const string tab="    ";
        cout << "[";
        for(int i=0; i<allNode.size(); i++) {
            cout << "\n"<< tab << "\"" << allNode[i]->data <<"\"";
            for(int j=0; j<allNode[i]->nextNList.size(); j++) {
                cout << "\n" << tab << tab << '\"' << allNode[i]->nextNList[j]->data << '\"';
            }
        }
        cout << "\n]\n";
    }


    void show(){
        clearGraph(ghead);
        cout << "[";
        showGraph(ghead, 1);
        cout <<"\n]\n";
        cout << "\n" << "show all route: " << endl;
        int shortest_step = gend->roads[0].size();
        for(int i=0; i<gend->roads.size(); i++) {
            vector<Node*> road = gend->roads[i];
            showRoute(road);
            shortest_step = shortest_step<road.size() ? shortest_step : road.size();
        }
        
        cout << "\n" << "show shortest route: " << endl;
        for(int i=0; i<gend->roads.size(); i++) {
            vector<Node*> road = gend->roads[i];
            if(road.size()==shortest_step) {
                showRoute(road);
            }
        }


    }




private:
    void showRoute(vector<Node*> road) {


        cout << "[ ";
        for(int j=0; j<road.size(); j++) {
            cout << '\"' << road[j]->data << "\"";
            if(j!=(road.size()-1))
                cout << "->";
        }
        cout << " ]\n";


    }


    void findR(Node* head, vector<Node*> rl) {
        rl.push_back(head);
        head->roads.push_back(rl);
        vector<Node*> irl = rl;
        for(int i=0; i<head->nextNList.size(); i++) {
            findR(head->nextNList[i], irl);
        }
    }


    void showGraph(Node* head, int lay){
        const string tab ="  ";
        cout << "\n";
        for(int i=0; i<lay; i++)
            cout << tab;
        cout << lay << "\"" << head->data <<"\"";
        lay++;
        for(int j=0; j<head->nextNList.size(); j++) {
            showGraph(head->nextNList.at(j), lay);
        }
    }


    /**
     * add node to graph
     */
    void addToGraph(Node* newNode) {
        // create two-dimensional plot
        int simily = nodeLen - changeStep;
        for(int i=0; i<allNode.size(); i++) {
            Node* oldNode = allNode[i];
            int similarity = compare(newNode, oldNode);
            if(similarity==simily) {
                newNode->nextNList.push_back(oldNode);
                oldNode->nextNList.push_back(newNode);
            }
        }
        // clear two-dimensional plot to one-way
        allNode.push_back(newNode);
    }


    void clearGraph(Node* node) {
        gend->nextNList.clear();
        vector<Node*> prevAll;
        vector<Node*> stack;


        stack.push_back(node);
        while(!stack.empty()) {
            Node* cur = stack[stack.size()-1];
            stack.pop_back();
        
            for(vector<Graph::Node*>::iterator itr=cur->nextNList.begin(); itr!=cur->nextNList.end();) {
                Node* cl = *itr;
                for(vector<Graph::Node*>::iterator itr2=cl->nextNList.begin(); itr2!=cl->nextNList.end();) {
                    Node* eqNode = *itr2;
                    if((cur->data == eqNode->data) || (find(prevAll.begin(), prevAll.end(), eqNode)!=prevAll.end())) {
                        cl->nextNList.erase(itr2);
                    }else{
                        ++itr2;
                    }
                }
                vector<Graph::Node*>::iterator index0 = stack.begin();
                stack.insert(index0, cl);


                ++ itr;
            }
            prevAll.push_back(cur);
        }
        findR(ghead, vector<Node*>());
    }


    /**
     *compare tow nodes gap
     */
    int compare(Node* n1, Node* n2) {
        int similarity = 0;
        for(int i=0; i<n1->data.length(); i++) {
            if(n1->data.at(i) == n2->data.at(i))
                similarity++;
        }
        return similarity;
    }
};


int main() {
    
    Graph* g = new Graph("hit", "cog", 3, 1);
    cout << "all graph nodes: " << endl;
    g->addNode("hot");
    g->addNode("dot");
    g->addNode("dog");
    g->addNode("lot");
    g->addNode("log");
    g->display();
    g->show();
    delete g;
}


注:没有处理开始和结束相同的情况



原创粉丝点击