最小操作数

来源:互联网 发布:国际象棋软件排名 编辑:程序博客网 时间:2024/05/18 01:24


给了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"。 


首先把所有的单词放到一个列表里面,然后组成一个无相图,然后从A点开始查找到B点的最短路径,使用了Dijkstra算法 来查找最短路径,然后把路径都打出来。。我用题目的测试用例是通过了,自己写了几个测试用例也过了,但是提交以后失败了。。。汗。。代码写得很匆忙。。非常乱哈。。总结一下再发出来,大家做过吗,都过了么。。。残念啊。。。好久没写过算法了,,被虐了。。。


#include <string>#include <vector>#include <iostream>#include <set>#include <map>#include <algorithm>using namespace std;class Solution{public:Solution(){};    //比较函数,比较两个字符串的差别是否为1,如果不唯一,返回-1    int cmp(string a,string b)    {        int flag=0;            for(int i= 0; i< a.size(); i++ )            {                if(a[i]!=b[i])                    flag++;                if(flag==2)                    return -1;            }   if(flag==1)       return 0;   else    return -1;        }//辅助函数,返回向量中最后一个元素的索引    int last(string str,vector<string> strv)    {        for(int i=0;i<strv.size();i++)            if(str == strv.at(i))                return i;        return -1;    } //计算路径    int Size(int a)        {            int b=a;            if(a==0)                return 9999;            else                return b;        }//辅助函数,显示 void display(vector< vector< string > > wayList)     {         for(int i=0;i<wayList.size();i++)             {                 for(int j=0;j<wayList[i].size();j++)                    cout << wayList[i].at(j) << "-->";                cout << endl;             }     }  //主函数    vector< vector<string> > findLadders(string start, string end, set<string>& dict)    {        vector< vector < string > > Res;    //返回值        set <string>::iterator si;              int max_len=dict.size()+2;          //向量的长度,+2表示起始字符串和结束字符串        /*二维向量保存各个路径,第一行表示start字符串,第二行表示end字符串,后面各行表示dict的各个字符串"hit"-->"hot"..."hit"-->"dot"......*/vector< vector< string > > wayList; //路径的二维向量,        vector<string> str;                 //保存所有字符串的向量if(start == end)    return Res;/*将数据添加到字符串向量中*/    str.push_back(start);    str.push_back(end);     for (si=dict.begin(); si!=dict.end(); si++)          {         str.push_back(*si);         } //构造二维向量列的长度     wayList.resize(max_len); //如果有向量和start只相差一个字符,就将向量添加到二维向量表中     for(int i=0;i<max_len;i++)        {            if(cmp(str.at(0),str.at(i))==0)                {                    wayList[i].push_back(str.at(i));                }        }  int flag=0;while(flag==0){    //检索所有向量    for(int i=0;i<max_len;i++)        {//不检索1式因为1保存的是end            if(i!=1)            {//检查所有向量              for(int j=0;j<max_len;j++)               {   //如果该列的向量大于0,表示有一条路径                 if(wayList[i].size()>0)                 {//比较该列最后一个元素是否有相邻的元素                                    if(cmp(wayList[i].back(),str.at(j))==0)                  {  //如果有,比较这条路径的长度和已知的路径长度的大小                   if(Size(wayList[j].size())>=Size(wayList[last(wayList[i].back(),str)].size())+1)                    {//如果这条路径长度小于已知路径,那将已知路径删除,变成这条路径wayList[j].clear();                        for(int t=0;t<wayList[last(wayList[i].back(),str)].size();t++)                            wayList[j].push_back(wayList[last(wayList[i].back(),str)].at(t));                        wayList[j].push_back(str.at(j));      //如果索引为1,表示已经检索到end字符串,表示已经找出来一条路径了                        if(j==1)                        {  //检查路径是否重复                         for(int m=0;m<Res.size();m++)                         {                           if(Res.at(m)==wayList[j])                               flag=1;                                                                                      }    //如果不重复,表示路径正确,添加到返回值中                         if(flag==0)                         {                             vector <string> res;                             for(int t=0;t<wayList[j].size();t++)                                 {                                     res.push_back(wayList[j].at(t));                                  }                             Res.push_back(res);                          }                         }//end if(j==1)                     }//end if(Size(wayList[j].size())>=Size(wayList[last(wayList[i].back(),str)].size())+1)                    }// end if(cmp(wayList[i].back(),str.at(j))==0)                   }// end if(wayList[i].size()>0)                  }//end for                   }// end if(i!=1)        }//end for//找到重复路径,表示已经检索完毕,结束循环    if(flag==1)        break;}//end whilefor(int i=0;i<Res.size();i++) {  Res[i].insert(Res[i].begin(),start);            }        return Res;     }};//start 提示:自动阅卷起始唯一标识,请勿删除或增加。int main(){       //vector < vector <string> > res;    set <string> strset;    strset.insert("hot");    strset.insert("dot");    strset.insert("dog");    strset.insert("lot");    strset.insert("log");    std::cout << "cog" <<std::endl;    Solution *s=new Solution();    res=s->findLadders("hit","cog",strset);for(int i=0;i<res.size();i++){for(int j=0;j<res[i].size();j++)cout << res[i].at(j) << "-->";cout << " " << endl;}    return 0;}

输出:

hit-->hot-->lot-->log-->cog--> 

hit-->hot-->dot-->dog-->cog--> 

结果还是失败。。呵呵。。。

原创粉丝点击