使用 BFS 的单词梯 2
Word ladder 2 using BFS
海编辑!!下面
我正在编写一个单词梯形图算法。用户输入开始词、结束词和所有单词的哈希。该算法返回从起始字到结束字的所有最短路径(如果存在多个(。例如 -> start_word = "冷" , end_word = "暖">
输出 = [[ 冷 -> 电源线>卡>病房>暖],[/如果存在另一条路径/]]。
前一个单词的每个连续单词都相差一个字符。我正在使用BFS搜索来解决这个问题。我的策略是返回所有路径,然后从返回的列表中选择最短的路径。这是我返回所有路径的代码:
auto word_ladder::generate(std::string const& from, std::string const& to, absl::flat_hash_set<std::string> const& lexicon) -> std::vector<std::vector<std::string>> {
absl::flat_hash_set<std::string> visited = {};
std::queue<std::vector<std::string>> search_queue = {};
std::vector<std::vector<std::string>> paths = {};
search_queue.push(std::vector<std::string>{from});
while (!search_queue.empty()) {
auto word = search_queue.front();
search_queue.pop();
auto neighbours = generate_neighbours(word.back(), lexicon);
for (auto &i: neighbours) {
auto new_word = word;
new_word.push_back(i);
if (i == to) {
paths.push_back(new_word);
continue;
}
if (visited.find(i) != visited.end()) {
continue;
}
search_queue.push(new_word);
visited.insert(i);
}
}
return paths;
}
它确实返回多个路径,但问题是它不会返回所有路径。它返回的路径之一是 ->
1(清醒,觉知,软件,分享,夏尔,希尔,希尔,纯粹,羊,睡眠
但是它不返回路径 -> 2("清醒","感知","软件","共享","sharn","shawn","shewn","sheen","sheep","sleep">
我很确定原因是因为我编码它的方式,它将"共享"一词标记为第一次遇到它时访问过(在 1 中(。因此,它不会通过第二条路径(在 2 中((
为了解决这个问题,我稍微改变了我的 for 循环:
for (auto &i: neighbours) {
auto new_word = word;
new_word.push_back(i);
if (i == to) {
paths.push_back(new_word);
continue;
}
for (auto &j: word) {
if (j == i) {
continue;
}
}
search_queue.push(new_word);
}
这个想法是检查该单词是否已在队列中跟踪的路径中访问过,而不是全局访问过。但是,由于某种原因,此解决方案卡在某个地方的循环中并且不会终止(我假设由于数据集很大?
我的代码在第二个有问题,还是由于数据集大而花费的时间太长?如何更好地实现解决方案?
编辑!!!
我现在不是找到所有路径,而是找到最短路径的长度,然后执行BFS直到该深度以获得该深度的所有路径。
auto word_ladder::generate(std::string const& from, std::string const& to, absl::flat_hash_set<std::string> const& lexicon) -> std::vector<std::vector<std::string>> {
absl::flat_hash_set<std::string> visited = {};
visited.insert(from);
std::queue<std::vector<std::string>> search_queue = {};
std::vector<std::vector<std::string>> paths = {};
search_queue.push(std::vector<std::string>{from});
auto length = find_shortest_path_length(from, to, lexicon);
std::cout << "length is: " << length << "n";
// auto level = 0;
std::unordered_map<std::string, int> level_track = {};
level_track[from] = 0;
while (!search_queue.empty() ) {
auto word = search_queue.front();
search_queue.pop();
// **
if (level_track[word.back()] <= length) {
auto neighbours = generate_neighbours(word.back(), lexicon);
const auto &parent = word.back();
for (auto &i: neighbours) {
auto new_word = word;
new_word.push_back(i);
if (i == to) {
paths.push_back(new_word);
std::cout << "The level at the path was " << level_track[parent] << "n";
continue;
}
if (path_crossed(word, i)) {
continue;
}
search_queue.push(new_word);
level_track[i] = level_track[parent] + 1;
}
}
}
return paths;
}
解决方案现在终止了,所以之前的问题肯定是大量的搜索。但是,我的算法仍然没有给我正确的答案,因为我跟踪节点(单词(深度的方式在某种程度上是不正确的。
您正在尝试找到一个有效的解决方案,但很可能它不存在。看到这个答案。枚举所有最短路径的成本可能非常高。
- 文本文件中的单词链表
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- 在指针的帮助下,文本文件中单词的频率
- 如何根据单词在文本中出现的概率输出单词
- 从字符串变量中逐字符读取单词
- 使用std::mt19937从字符串中返回一个随机单词
- 如何用for循环在c++中生成单词三角形
- 将数字转换为单词
- 如何用C++编写BFS函数
- 使用if-else将数字转换为单词
- C++-字符串是否包含一个带有简单循环的单词
- 使用单词"not"作为C ++类的名称会导致VS2019错误
- 使用 bfs 解决连接组件问题时得到错误的答案
- 为什么这个程序返回最后一个单词而不是最长的单词?
- 3-3. 编写一个程序来计算每个不同单词在其输入中出现的次数
- C++为一串单词添加空格
- 在C++中查找(奇怪的)字符串中的单词
- 使用 BFS 的单词梯 2
- 如何打印 BFS 路径本身而不是此单词梯的路径长度?
- 这个算法获取所有单词梯的时间复杂度是多少?