如何轻松快速地存储大型word数据库? 我目前正在开发一个C++开发的拼写检查程序。对于检查单词是否存在的部分,我目前执行以下操作: 我在网上找到了一个包含所有英文单词的.txt文件 我的脚本首先遍历这些文本文件,并将每个文本文件 在地图对象中显示其条目,以便轻松访问

如何轻松快速地存储大型word数据库? 我目前正在开发一个C++开发的拼写检查程序。对于检查单词是否存在的部分,我目前执行以下操作: 我在网上找到了一个包含所有英文单词的.txt文件 我的脚本首先遍历这些文本文件,并将每个文本文件 在地图对象中显示其条目,以便轻松访问,c++,database,dictionary,words,C++,Database,Dictionary,Words,这种方法的问题是,当程序启动时,步骤2)大约需要20秒。这本身并不是什么大问题,但我想知道你们中是否有人想到了另一种方法来快速获取我的词汇数据库。例如,是否有一种方法可以将map对象存储在文件中,这样我就不必每次都从文本文件构建它?如果包含所有英文单词的文件不是动态的,您可以将其存储在静态地图中。为此,您需要解析.txt文件,如: 阿尔法 贝塔 伽马射线 要将其转换为类似以下内容: static std::map<std::string,int> wordDictionary =

这种方法的问题是,当程序启动时,步骤2)大约需要20秒。这本身并不是什么大问题,但我想知道你们中是否有人想到了另一种方法来快速获取我的词汇数据库。例如,是否有一种方法可以将map对象存储在文件中,这样我就不必每次都从文本文件构建它?

如果包含所有英文单词的文件不是动态的,您可以将其存储在静态地图中。为此,您需要解析.txt文件,如:

阿尔法

贝塔

伽马射线

要将其转换为类似以下内容:

static std::map<std::string,int> wordDictionary = {
                { "alpha", 0 },
                { "beta", 0 },
                { "gamma", 0 } 
                   ... };
static std::map wordDictionary={
{“alpha”,0},
{“beta”,0},
{“gamma”,0}
... };
您可以通过编程或在您喜爱的文本编辑器中使用“查找并替换”来完成此操作


您的.exe将比以前重很多,但它的启动速度也将比从文件中读取此信息快得多。

我有点惊讶,还没有人想到序列化。Boost为这种解决方案提供了强大的支持。如果我理解正确的话,问题在于每当使用应用程序时,读入单词列表(并将它们放入数据结构中,希望能够提供快速查找操作)所需的时间太长。构建这样一个结构,然后将其保存到二进制文件中供以后重用,这将提高应用程序的性能(基于下面给出的结果)

下面是一段代码(同时也是一个简单的工作示例),它可能会在这方面帮助您

#include <chrono>
#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
#include <stdexcept>
#include <string>

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/set.hpp> 

#include "prettyprint.hpp"

class Dictionary {
public:
  Dictionary() = default;
  Dictionary(std::string const& file_)
    : _file(file_)
  {}

  inline size_t size() const { return _words.size(); }

  void build_wordset()
  {
    if (!_file.size()) { throw std::runtime_error("No file to read!"); }

    std::ifstream infile(_file);
    std::string line;

    while (std::getline(infile, line)) {
      _words.insert(line);
    }
  }

  friend std::ostream& operator<<(std::ostream& os, Dictionary const& d)
  {
    os << d._words;  // cxx-prettyprint used here
    return os;
  }

  int save(std::string const& out_file) 
  { 
    std::ofstream ofs(out_file.c_str(), std::ios::binary);
    if (ofs.fail()) { return -1; }

    boost::archive::binary_oarchive oa(ofs); 
    oa << _words;
    return 0;
  }

  int load(std::string const& in_file)
  {
    _words.clear();

    std::ifstream ifs(in_file);
    if (ifs.fail()) { return -1; }

    boost::archive::binary_iarchive ia(ifs);
    ia >> _words;
    return 0;
  }

private:
  friend class boost::serialization::access;

  template <typename Archive>
  void serialize(Archive& ar, const unsigned int version)
  {
    ar & _words;
  }

private:
  std::string           _file;
  std::set<std::string> _words;
};

void create_new_dict()
{
  std::string const in_file("words.txt");
  std::string const ser_dict("words.set");

  Dictionary d(in_file);

  auto start = std::chrono::system_clock::now();
  d.build_wordset();
  auto end = std::chrono::system_clock::now();
  auto elapsed =
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

  std::cout << "Building up the dictionary took: " << elapsed.count()
            << " (ms)" << std::endl
            << "Size of the dictionary: " << d.size() << std::endl;

  d.save(ser_dict);
}

void use_existing_dict()
{
  std::string const ser_dict("words.set");

  Dictionary d;

  auto start = std::chrono::system_clock::now();
  d.load(ser_dict);
  auto end = std::chrono::system_clock::now();
  auto elapsed =
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

  std::cout << "Loading in the dictionary took: " << elapsed.count()
            << " (ms)" << std::endl
            << "Size of the dictionary: " << d.size() << std::endl;
}

int main()
{
  create_new_dict();
  use_existing_dict();
  return 0;
}
依赖项:

  • (但是,我使用了1.58版)

希望这有帮助。:)干杯。

第一件事优先。不要使用地图(或集合)存储单词列表。使用字符串向量,确保其内容已排序(我相信您的单词列表已排序),然后从标题中使用binary\u find检查单词是否已在词典中


尽管这可能仍然是高度次优的(取决于编译器是否进行了小字符串优化),但您的加载时间将至少提高一个数量级。做一个基准测试,如果你想让它更快,在字符串向量上再贴一个问题。

你一直在说数据库。。。为什么不使用一个呢?为什么不将它静态地存储到内存中呢?可以使用SQLite数据库。我没有找到任何以文本以外的格式分布的所有英语单词集。。你想到一个特别的吗?谢谢你help@FrankS101实际上这就是我想做的,但是有没有办法把地图保存到静态内存中呢?我很好奇。“静态(内存/映射)”≈ “硬代码”,对吗?@cpp初学者完全正确。谢谢,我还找到了更多关于“静态内存”的信息:非常感谢@laszlzso,我将深入研究它,但根据您提到的编译时间,它似乎是一个顶级解决方案!非常欢迎。请注意,这不是编译时间——首先,它是构建单词集所花费的时间(以毫秒为单位);第二次,对保存的集进行反序列化(从二进制文件加载)所需的操作。
Building up the dictionary took: 810 (ms)
Size of the dictionary: 466544
Loading in the dictionary took: 271 (ms)
Size of the dictionary: 466544