用字符A-Z替换字符串中的每个字母(运行时问题)

时间:2018-04-20 16:10:14

标签: c++ runtime

我正在编写一个拼写检查程序,如果单词拼写错误,会生成建议。生成建议的算法之一用A-Z中的每个字母替换单词中的每个字母(例如,如果'phkne'被拼写检查,则会找到单词'phone')。这是我用来做这个的当前功能

//replace each letter in the word with all letters from the alphabet
void replaceLetters(string word, Hashtable & wordList)
{
  char letters[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  string copy = word;
  for (int i = 0; i < word.length() + 1; i++)
    {
      for (int j = 0; j < 25; j++)
        {
          copy = word;
          replace(copy.begin(), copy.end(), copy[i], letters[j]);
          if (wordList.contains(copy))
            {
                  cout << copy << endl; 
            }
        }
    }
}

此解决方案有效,但运行时非常慢。我假设字母的字符和嵌套的for循环减慢了,但我不能推理更快的解决方案。

这是我的Hash表实现中的contains函数

bool Hashtable::contains(string item)
{
  for (int i = 0; i < size; i++)
    {
      for (int j = 0; j < table[i].size() + 1; j++)
        {
          if (table[i].get(j) == item)
            {
               return true;
            }
        }
    }
  return false;
}

2 个答案:

答案 0 :(得分:1)

速度在很大程度上取决于doctrine_mongodb: default_database: "%mongodb_database%_%kernel.environment%" default_document_manager: default connections: default: server: "mongodb://%mongodb_host%:%mongodb_port%" options: db: "%mongodb_database%_%kernel.environment%" connect: true # timeout: connectTimeoutMS: 60000 socketTimeoutMS: 60000 wTimeoutMS: 60000 shared: server: "mongodb://%mongodb_host%:%mongodb_port%" options: db: "%mongodb_database%_shared" connect: true default_connection: default document_managers: . . . . 的实现,因为在代码的最热路径中调用了Hashtable方法。 您发布的contains()方法表明您的方法根本不是哈希表,并且由于它执行详尽的搜索,因此速度非常慢。

不要重新发明轮子(尤其是使用非常慢的轮子),请务必使用尽可能快的哈希表(最快阅读,而不是写作)。可能是contains()std:unordered_map,但要做你的研究。

也许您也可以尝试不同的算法,例如使用一些启发式算法来避免搜索可能解决方案的整个空间。一种可能是计算单词和字典中每个单词之间的Levenshtein distance,保留一个短距离列表。

答案 1 :(得分:0)

您应该使用另一个容器来容纳wordList。使用std::setstd:unordered_set字符串。 std::setstd:unordered_set慢,但需要的内存更少。 如果你能够使用更多内存,那么你应该使用std:unordered_set - 它更快。使用find()方法查找可能的密钥。

同样重要的是将这个任务分成几个线程。要得到  要执行的最大线程数,您可以使用std::thread::hardware_concurrency()方法。它返回支持的并发线程数。 因此,例如,您可以在相等的部分上分离算法,以计算每个线程的组合部分。 但没有简单的解决方案。需要测试并检查哪种方式更好。其中一些想法可以帮到你。