【发布时间】:2020-12-28 04:53:37
【问题描述】:
我正在尝试创建一个程序来查看字符串的所有排列,然后打印出所有有效的单词。我可以获得所有排列,但检查一个单词是否在字典文本文件中大约需要 3 秒。当我尝试 7 个字母时,花了 47:19。有什么方法可以更快地从文件中读取?
任何帮助将不胜感激。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
bool in(std::string arr, char element)
{
for (int i = 0; i < arr.size(); i++)
{
if (arr[i] == element)
{
return true;
}
}
return false;
}
bool inDictionary(std::string str)
{
std::ifstream dictionary;
dictionary.open("words.txt");
if (dictionary.is_open())
{
std::string word;
while (std::getline(dictionary, word))
{
if (word == str)
{
return true;
}
}
}
return false;
}
std::string remainingCharacters(std::string orginal, std::string newString)
{
std::string characters = "";
for (int i = 0; i < orginal.size(); i++)
{
if (!in(newString, orginal[i]))
{
characters += orginal[i];
}
}
return characters;
}
void combinations(std::string cur, std::string original, std::vector<std::string>& permutations)
{
for (int i = 0; i < remainingCharacters(original, cur).size(); i++)
{
permutations.push_back(cur + remainingCharacters(original, cur)[i]);
combinations(cur + remainingCharacters(original, cur)[i], original, permutations);
}
}
int main()
{
std::vector<std::string> permutations;
combinations("", "wdsrock", permutations);
for (int i = 0; i < permutations.size(); i++)
{
if (inDictionary(permutations[i]))
{
std::cout << permutations[i] << ", ";
}
}
;
}
【问题讨论】:
-
如果字典不是太大,您可以在查找
inDictionary之前提前将其全部读入内存,即缓存它。 -
如果要查找3个字,需要调用
inDictionary3次,每次打开一个文件,从文件开头开始?如果您有一个包含 1000 个单词的列表要搜索怎么办?简而言之,您当前的方法存在很大缺陷。读取文件一次,将信息存储在某处,然后搜索特定的存储,无论是数组、哈希表等,不是更有意义吗? -
一个比让你的慢步更快更好的问题可能是问你如何减少调用慢步的频率。这是您能想到的唯一方法(遍历排列;在文件的每次迭代中循环)吗?我将提出一个挑战:尝试只通过一次文件即可完成您的目标,而无需致电
combinations()。 -
@JaMiT 谢谢,我在程序开始时将文本文件存储到无序映射中,并使用 std::unordered_map::find() 快速遍历文件。现在需要不到一秒钟的时间。最后一个问题,最好使用无序映射,还是应该使用数组?
-
取决于您在做什么以及您拥有多少数据。想象一下,您的字典中有一千个项目,并且必须一直
if (arr[i] == element)所有这些项目。呸呸呸。unsorted_map使用更智能的算法进行查找,它将您的输入转换为数字并将该数字用作数组索引。有时它必须做更多的工作,太多的输入映射到相同的数字,算法必须找出数组索引的许多项目中的哪一个是正确的,但通常主要成本是将输入转换为索引它只发生一次。
标签: c++