我怎样才能找到部分单词匹配/找到c ++

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我怎样才能找到部分单词匹配/找到c ++相关的知识,希望对你有一定的参考价值。

我正在制作一个类似拼字游戏的游戏。我的目标是有5个随机字母,这些字母可能与我制作的字典中的至少一个单词匹配,因此游戏可以开始。我已经完成了这个,但由于5个字母是随机的,因此它很可能会匹配字典中的一个单词。我已经完成了测试运行并获得了随机字母,但每次都没有匹配(但它的工作硬编码)。我想如果我能找到一个部分匹配,我可以保留构成单词一部分的字母,并为那些没有单词的字母保留不同的字母。问题是,我不知道该怎么做。

这是我的五个随机字母的代码:

void fiveLetters()
{
    srand(time(NULL));

    for (int i =0; i<=4; i++) // display 5 random letters
    {
        int n = rand()%26;
        char letter = (char)(n+97);
        letters[i] = letter;
        cout << letters[i]<< " ";
    }
    letters[5] = ''; // last value in char array null value so I can convert to string
    attempt = letters; // the 4 letters

    checkWords();
}

检查它是否与我使用的单词匹配:

void checkWords()
{
    if (find(words.begin(),words.end(), attempt) != words.end()) // if matches word in set
    {
        cout << " Words found" << endl;
    }
    else // if it doesn't match
    {
        cout << "cannot find word " << endl;
        attempt.clear();
        fiveLetters();
    }
}

字典是一个包含大量单词的文本文件,但是因为我只是在实现它之前试图让事情起作用,所以我使用5-10个单词并将它们放在set<string>中。对不起,长时间阅读,任何帮助表示赞赏!

答案

此示例演示如何使用Trie递归搜索加载到其中的单词,使用搜索条件,如可用字母数,最小字长和最大数量的“缺失”字母 - 使用的字母不包含在“可用”中“ 信件。

这个Trie是一个26-ary树,所以每个节点有26个子节点,每个字母对应一个字母。使用单词中的第一个字母选择根节点的子节点,第二个字母选择此子节点中的一个,依此类推。节点包含一个布尔值,表示单词以该节点结束。然而,这样的节点不是“叶子”,因为终止的单词可能是较长单词的前缀(节点终止“球”,但仍具有“气球”的子分支)。

Trie以及递归搜索对于您的特定任务来说非常快速。 (顺便说一句,递归搜索不使用递归函数,它将每个级别的上下文存储在基于矢量的堆栈上)。

#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <fstream>
#include <random>
#include <algorithm>

class Trie {
    // branch_count defines the number of characters which are combined to make words
    // 26 is the number of letters, interpreted case-insensitively
    static const int branch_count = 26;
    // index_map takes a character and returns a number between 0 and branch_count-1
    static int index_map(char c) {
        if((c >= 'a') & (c <= 'z')) return c - 'a';
        if((c >= 'A') & (c <= 'Z')) return c - 'A';
        return -1;
    }
    // index_unmap takes an index, between 0 and branch_count-1, and returns
    // the canonical character representation for that index
    static char index_unmap(int index) {
        return char('a' + index);
    }
    // verify_word returns true if all characters in the string map to an index
    // returns false if at least one character is not recognized
    static bool verify_word(const std::string& word) {
        for(auto&& c : word) {
            if(index_map(c) == -1) return false;
        }
        return true;
    }
    // Node is the Trie's branch_count-ary tree node class
    struct Node {
        Node* child_nodes[branch_count];
        bool terminates_word;
        Node() : terminates_word(false) {
            for(auto& p : child_nodes) { p = nullptr; }
        }
    };
    // make_lower(str) changes upper-case letters in str to lower-case (in-place)
    static void make_lower(std::string& str) {
        for(auto& c : str) {
            if((c >= 'A') & (c <= 'Z')) {
                c += 'a' - 'A';
    }   }   }
    // is_space_char(x) returns true when c is some kind of 
    // unprintable or blank, but nonzero, character
    static bool is_space_char(char c) { return (c > 0) & (c <= ' '); }

    // trim(str) removes whitespace from the left and right sides
    // of str (str is modified in-place)
    static void trim(std::string& str) {
        const auto len = str.length();
        if(!len) return;
        auto i = len-1;
        if(is_space_char(str[i])) {
            for(--i; i+1; --i) {
                if(!is_space_char(str[i])) {
                    str.resize(i+1);
                    break;
        }   }   }
        if(!(i+1)) {
            str.clear();
            return;
        }
        i=0;
        if(is_space_char(str[i])) {
            for(++i;; ++i) {
                if(!is_space_char(str[i])) {
                    str = str.substr(i);
                    return;
    }   }   }   }
    Node *root;
    int node_count;
    int word_count;

public:
    // Trie::AddWord(word) stores a string in the Trie
    void AddWord(std::string word) {
        if(word.empty()) return;
        make_lower(word);
        if(!verify_word(word)) return;
        Node *p = root;
        for(const auto c : word) {
            const int child_index = index_map(c);
            if(child_index == -1) {
                // verify_word(word) should have caught this.
                // Well-behaved, but might use excess memory.
                return;
            }
            Node *pchild = p->child_nodes[child_index];
            if(!pchild) {
                p->child_nodes[child_index] = pchild = new Node;
                ++node_count;
            }
            p = pchild;
        }
        if(!p->terminates_word) {
            p->terminates_word = true;
            ++word_count;
    }   }

    // LoadWords(input_stream) loads all line-delimited words from
    // the stream into the Trie
    int LoadWords(std::istream& stream_in) {
        const int start_count = word_count;
        std::string line;
        while(std::getline(stream_in, line)) {
            trim(line);
            AddWord(line);
        }
        return word_count - start_count;
    }
    // LoadWords(filename) loads all line-delimited words from
    // the file at the given path
    int LoadWords(const std::string& file_path) {
        std::ifstream stream_in(file_path.c_str());
        return LoadWords(stream_in);
    }
    // WordCount() returns the number of words loaded so far
    int WordCount() const { return word_count; }

    // select_type is a helper for specifying iterator behavior
    template <bool select_A, typename A, typename B>
    struct select_type { typedef A type; };
    template <typename A, typename B>
    struct select_type<false, A, B> { typedef B type; };
    template <bool select_A, typename A, typename B>
    using select_type_t = typename select_type<select_A, A, B>::type;

    // The iterator class is used for begin() and end(), as a minimal
    // implementation compatible with range-based for,
    // as well as by the destructor when destroying the
    // tree's Node objects.
    template <bool is_const=true, bool delete_iter=false>
    class iterator {
        friend class Trie;
        typedef select_type_t<is_const, const Node*, Node*> pnode_t;
        struct context {
            pnode_t node;
            int     child_index;
        };
        std::vector<context> stack;

        pnode_t advance() {
            for(;;) {
                if(stack.empty()) return nullptr;
                pnode_t p = stack.back().node;
                int &child_index = stack.back().child_index;
                while(++child_index < branch_count) {
                    pnode_t pchild = p->child_nodes[child_index];
                    if(pchild) {
                        stack.push_back({pchild, -1});
                        if(!delete_iter && pchild->terminates_word) return nullptr;
                        break;
                }   }
                if(stack.back().child_index == branch_count) {
                    stack.pop_back();
                    if(delete_iter) return p;
        }   }   }
    public:
        iterator(pnode_t root) {
            stack.push_back({root, -1});
            if(!delete_iter) advance();
        }
        iterator() {}
        std::string operator * () const {
            if(stack.empty()) return std::string();
            std::string word;
            for(int i=0; stack[i].child_index != -1; ++i) {
                word += index_unmap(stack[i].child_index);
            }
            return word;
        }
        iterator& operator ++ () {
            advance();
            return *this;
        }
        bool operator != (const iterator& iter) const {
            if(stack.size() != iter.stack.size()) return true;
            const int size = static_cast<int>(stack.size());
            for(int i=0; i<size; ++i) {
                if(stack[i].node != iter.stack[i].node) return true;
            }
            return false;
        }
    };
    // ctor
    Trie() : root(new Node), node_count(1), word_count(0) {}
    // dtor
    ~Trie() {
        iterator<false, true> iter(root);
        int count = 0;
        while(auto pn = iter.advance()) {
            delete pn;
            ++count;
        }
        //std::cout << "Final word count: " << word_count << '
';
        //std::cout << count << " of " << node_count << " Node objects deleted
";
    }

    // const_iterator defined from iterator with template parameter 
    // for selecting const Node pointers
    typedef iterator<true> const_iterator;
    const_iterator  begin() const { return const_iterator(root); }
    const_iterator  end()   const { return const_iterator(); }

    // FindWords:

以上是关于我怎样才能找到部分单词匹配/找到c ++的主要内容,如果未能解决你的问题,请参考以下文章

我怎样才能找到任何字符的立即重复?

我怎样才能找到我在两个地点之间旅行的距离和时间?

从输入字段中查找部分单词匹配,我还发现来自 HTML 代码的结果。为啥?

我怎样才能使这个 JSON 数据在 API 上可用?

类型不匹配。必需:布尔值,在 Scala 中找到:Future[Boolean]

从端口C#二进制数据转换为十六进制字符串