Word ladders II

此题烦扰我多天,核心算法实际上就是书上给出的伪代码,需要认真阅读!但仍有许多部分需要完善
核心思想的伪代码

先贴代码

#include "string"
#include "lexicon.h"
#include "queue.h"
#include "simpio.h"
#include "vector.h"
#include "console.h"
#include "map.h"
#include <iostream>

using namespace std;

Vector<string> Findladders(const string &start,const string &end,const Lexicon wordlist)
{
Queue<Vector<string>> paths;
Vector<string> first;
Set<string> usedword;
Vector<string> shortest;//表示当前处理路径
first.add(start);
paths.add(first);
usedword.add(start);

while(!paths.isEmpty())
{
    shortest =paths.dequeue();
    string lastword = shortest.back();
    if(lastword == end)
    {cout<<"Found ladder:";
    return shortest;}
    else
    {

        for(int a=0; a<lastword.length(); a++)
        {
            for(char b ='a'; b<='z';b++)
            {   string copy = lastword;
                copy[a] = b;
                if (wordlist.contains(copy) && !usedword.contains(copy))
                {
                    usedword.add(copy);
                    Vector<string> laddercopy = shortest;
                    laddercopy.add(copy);
                    paths.add(laddercopy);
                }
            }
        }

    }

}
cout<<"No ladder found";
Vector<string> a;
return a;
}
int main() {

// [TODO: fill in the code]
Lexicon wordlist("EnglishWords.txt");
while(true)
{
   string start = ""; string end = "";
   Vector<string>ladders;
   cout<<"Enter start word(RETURN to quit): ";
   cin>>start;
   cout<<"Enter distination word: ";
   cin>>end;
   ladders = Findladders(start,end,wordlist);
   cout<<ladders<<endl;
}
return 0;
}

运行结果:
运行结果
要求输出一个最短的结果,用DFS,将单词变化(只有一个字母与前一个单词不同)的所有可能路径(实际上是从短到长)存放在一个Queue<Vector>里,当有一个路径终点是目标单词时,我们则找到了最短的路径。我们根据Queue的先入先出原则,每次都从头开始选择一个路径,判断它是否是目标路径,若不是,则删除。

存在几个问题:
1) 我们输入的起始单词是一个string,如何转化为一个只含这一个单词的路径?
实际上,我们的实现函数为:VectorFindladder(const string & start, const string &end, const Lexicon & wordlist>【注意参数的传递形式!】
函数一开始就定义Queue、Vector变量,将string add入Vector,Vector add入Queue里,即可解决。

2) 因为所有单词的引用都是const,所以当需要修改单词时,就要复制一个拷贝

主体是一个while函数,当结尾单词非目标单词时,我们需要将当前路径复制一个拷贝,把新变化的单词加入到这个复制的路径中去,再将这个复制的并添加了一个单词的路径加入到路径集Vector中去。因为原来的路径要被删除,新生成的路径与原来的路径只差一个单词,所以1.我们需要复制 2.这个路径集里的路径长度是递增的:先生成所有长度为2的路径,再生成所有长度为3的路径……可知我们求得的第一个目标路径就是最短的。
还要注意用一个Vectorusedword保存使用过的单词,避免产生死循环。

存在一些疑问:题目提示用Vector储存每一个路径,可是输出时每个单词就会带引号(示例中不带引号),如何处理?
No ladder found时如何不输出空Vector?

猜你喜欢

转载自blog.csdn.net/weixin_43846562/article/details/90436851