C++ 处理字谜的算法优化

C++ 处理字谜的算法优化,c++,algorithm,C++,Algorithm,我正在做一个项目,在某个时候,我需要接受字母,然后通过我拥有的单词词典进行搜索,并从词典中输出所有单词,这些单词是我接受的字母的拼字法可以找到的 例如,如果我接受字母odg 该程序将从字典中查找单词dog和god。 我面临的问题是,如果我接受更多的字母,程序将永远无法输出。我有点理解为什么,因为字谜基本上是给定字母的阶乘,而且增长得非常快。我想知道我是否可以修改我已经编写的代码,使这个程序更快 我将在这里发布3个函数,这就是可怕的减速发生的地方。请注意,我的字典存储在二进制搜索树中 //look

我正在做一个项目,在某个时候,我需要接受字母,然后通过我拥有的单词词典进行搜索,并从词典中输出所有单词,这些单词是我接受的字母的拼字法可以找到的

例如,如果我接受字母odg 该程序将从字典中查找单词dog和god。 我面临的问题是,如果我接受更多的字母,程序将永远无法输出。我有点理解为什么,因为字谜基本上是给定字母的阶乘,而且增长得非常快。我想知道我是否可以修改我已经编写的代码,使这个程序更快

我将在这里发布3个函数,这就是可怕的减速发生的地方。请注意,我的字典存储在二进制搜索树中

//lookup accepts the letters, which will be rearrange and searched in the BST
//it accepts function pointer callback, but do not worry about it, its just the   //way to output the words that I found.
    void DictionaryImpl::lookup(string letters, void callback(string)) const
    {
        if (callback == nullptr)
            return;

        removeNonLetters(letters);
        if (letters.empty())
            return;

        string permutation = letters;


        string tempString;

        do
        {   
            tempString=findValue(root, permutation);

            if(tempString !="!!!ValueNotFound!!!")
                callback(tempString);

            generateNextPermutation(permutation);
        } while (permutation != letters);

    }


//findValue accepts pointer to the root of the tree
//and it accepts the string that it is searching
    string DictionaryImpl::findValue(Node* p, string searchValue) const
    {
                if(p !=nullptr)
        {
            if(p ->data == searchValue)
                return searchValue;
            else if(p->data > searchValue)
                return findValue(p->left,searchValue);
            else if(p->data < searchValue)
                return findValue(p->right,searchValue);
        }
        return "!!!ValueNotFound!!!";
    }

    //accepts a string that it is going to rearrange
    void generateNextPermutation(string& permutation)
    {
        string::iterator last = permutation.end() - 1;
        string::iterator p;

        for (p = last; p != permutation.begin()  &&  *p <= *(p-1); p--)
            ;
        if (p != permutation.begin())
        {
            string::iterator q;
            for (q = p+1; q <= last  &&  *q > *(p-1); q++)
                ;
            swap(*(p-1), *(q-1));
        }
        for ( ; p < last; p++, last--)
            swap(*p, *last);
    }
//lookup接受字母,这些字母将在BST中重新排列和搜索
//它接受函数指针回调,但不用担心,它只是//输出我找到的单词的方法。
void DictionaryImpl::lookup(字符串字母,void回调(字符串))常量
{
if(回调==nullptr)
回来
删除字母(字母);
if(letters.empty())
回来
字符串排列=字母;
字符串tempString;
做
{   
tempString=findValue(根,置换);
if(tempString!=“!!!ValueNotFound!!!”)
回调(tempString);
生成置换(置换);
}while(排列!=字母);
}
//findValue接受指向树根的指针
//它接受它正在搜索的字符串
字符串字典impl::findValue(节点*p,字符串搜索值)常量
{
如果(p!=nullptr)
{
如果(p->data==搜索值)
返回搜索值;
else if(p->data>searchValue)
返回findValue(p->left,searchValue);
else if(p->data右侧,searchValue);
}
return“!!!ValueNotFound!!!”;
}
//接受要重新排列的字符串
void generatenext排列(字符串和排列)
{
string::iterator last=permutation.end()-1;
字符串::迭代器p;

对于(p=上;p!=置换)(开始)和*p < p>,C++标准库已经具有结构(例如,代码>设置<代码>,或使用<代码>下拉绑定> <代码> < <代码>向量>代码>和正在执行的算法(<代码> NExtx置换>代码> >;使用这些代码可能比编写自己的解决方案更有效率。

但正如你所说的,阶乘增长非常快:你需要的是一个新的算法。这里有一个标准技巧:两个字符串在排序后如果且仅当它们相同时才是彼此的字谜。例如,排序
dog
god
都给出
dgo

通过使用排序后的版本,您完全不需要迭代排列。(在实现这些方法时,了解
multimap
可能会有所帮助)


(另一种选择是使用
multiset
s个字符;同样,multiset{d,o,g}和{g,o,d}比较相等。但是使用排序字符串会更有效)

提高代码性能的最佳方法是使用分析工具查找瓶颈。当然,处理这一问题的最佳方法是……搜索……哦,伙计,排序后的单词将相等的想法非常好,这正是我需要的,非常感谢。还有一件事,我应该在这里使用哪种排序算法?无法做到,project不需要实现任何尚未提供的东西。我知道如何进行快速排序,这在这里好吗?@user1335175:老实说,我会使用冒泡排序。它写起来非常快,很难搞乱。如果你更习惯的话,可以改为插入排序或选择排序。我认为你正在排序的任何东西都不会太长让它值得花时间写和调试更复杂的东西——除非你已经有一个可以写的和工作的程序,你可以为这个项目再使用。但是,你被教忽略C++标准库是很可惜的,但是这是一个很坏的习惯。(…我认为插入排序是有效排序短序列的流行选择。