C++ 如何在与用户给定前缀匹配的字符串向量中找到第一个单词?

C++ 如何在与用户给定前缀匹配的字符串向量中找到第一个单词?,c++,string,vector,C++,String,Vector,假设我有一个字符串的排序向量: std::vector<std::string> Dictionary Dictionary.push_back("ant"); Dictionary.push_back("anti-matter"); Dictionary.push_back("matter"); Dictionary.push_back("mate"); Dictionary.push_back(&qu

假设我有一个字符串的排序向量:

std::vector<std::string> Dictionary
Dictionary.push_back("ant");
Dictionary.push_back("anti-matter");
Dictionary.push_back("matter");
Dictionary.push_back("mate");
Dictionary.push_back("animate");
Dictionary.push_back("animal");
std::sort(Dictionary.begin(), Dictionary.end());
并将其用作std::find_if函数的谓词,以查找第一个匹配项的迭代器。但如何搜索用户给定的字符串作为前缀?有可能以某种方式使用二进制谓词吗?或者构建一个依赖于变量和参数的伪一元谓词

或者,在这个问题中是否有其他容器和方法应该使用

我知道有更高效、更优雅的结构来存储用于前缀搜索的词典,但我是一个自学编程初学者,因此首先我想学习如何使用标准容器,然后再尝试更复杂的结构。

您可以将find_prefix编写为lambda。用于捕获要搜索的字符串,并将其用于比较:

string word = ...  // the prefix you're looking for
auto result = std::find_if(Dictionary.begin(), Dictionary.end(), 
                           [&word](string const &S) {
                           return ! S.compare(0, word.length(), word);
});
您可以将find_前缀写为lambda。用于捕获要搜索的字符串,并将其用于比较:

string word = ...  // the prefix you're looking for
auto result = std::find_if(Dictionary.begin(), Dictionary.end(), 
                           [&word](string const &S) {
                           return ! S.compare(0, word.length(), word);
});

由于您正在对向量进行排序,因此应该利用向量已排序的优势

与对匹配项进行线性搜索不同,如果与前缀匹配的条目不正确,您可以使用将其置于以下位置:

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

int main()
{
    std::vector<std::string> Dictionary;
    Dictionary.push_back("ant");
    Dictionary.push_back("anti-matter");
    Dictionary.push_back("matter");
    Dictionary.push_back("mate");
    Dictionary.push_back("animate");
    Dictionary.push_back("animal");
    std::sort(Dictionary.begin(), Dictionary.end());
    
    std::vector<std::string> search_test = {"an", "b", "ma", "m", "x", "anti"};
    for (auto& s : search_test)
    {
        auto iter = std::lower_bound(Dictionary.begin(), Dictionary.end(), s);
    
        // see if the item returned actually is a match
        if ( iter->size() >= s.size() && iter->substr(0, s.size()) == s )
            std::cout << "The string \"" << s << "\" has a match on \"" << *iter << "\"\n";
        else
           std::cout << "no match for \"" << s << "\"\n";
    }
}

完成下界后的测试,以查看字符串是否与下界找到的字符串匹配。

因为您正在对向量进行排序,所以应该利用向量已排序的优势

与对匹配项进行线性搜索不同,如果与前缀匹配的条目不正确,您可以使用将其置于以下位置:

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

int main()
{
    std::vector<std::string> Dictionary;
    Dictionary.push_back("ant");
    Dictionary.push_back("anti-matter");
    Dictionary.push_back("matter");
    Dictionary.push_back("mate");
    Dictionary.push_back("animate");
    Dictionary.push_back("animal");
    std::sort(Dictionary.begin(), Dictionary.end());
    
    std::vector<std::string> search_test = {"an", "b", "ma", "m", "x", "anti"};
    for (auto& s : search_test)
    {
        auto iter = std::lower_bound(Dictionary.begin(), Dictionary.end(), s);
    
        // see if the item returned actually is a match
        if ( iter->size() >= s.size() && iter->substr(0, s.size()) == s )
            std::cout << "The string \"" << s << "\" has a match on \"" << *iter << "\"\n";
        else
           std::cout << "no match for \"" << s << "\"\n";
    }
}

下界后的测试是为了查看字符串是否与下界找到的字符串匹配。

std::set省去了排序的麻烦,并且可以确保每个单词只出现一次。C++20将使成员函数的开头变得简单。在此之前,串联的查找和比较函数将使您达到目的。此外,如果不是std::set,则在向量上调用std::sort,然后使用std::lower_bound或std::upper_bound将比线性搜索快得多。想象一下,如果有数千个字符串。我第一次尝试将字典作为一个集合来实现,但我认为我无法在此容器中使用find_if。std::find_if与std::set配合使用效果很好。std::set为您省去了排序的麻烦,并且您可以确保每个单词只出现一次。C++20将使成员函数的开头变得简单。在此之前,串联的查找和比较函数将使您达到目的。此外,如果不是std::set,则在向量上调用std::sort,然后使用std::lower_bound或std::upper_bound将比线性搜索快得多。想象一下,如果有数千个字符串。我第一次尝试将字典作为一个集合来实现,但我认为我无法在此容器中使用find_if。std::find_if与std::set配合使用效果很好。谢谢!我尝试过使用lambda函数,但我无法通过第一个示例。所以我可以在括号中使用任意数量的参数?是的,您可以捕获多个变量。谢谢!我尝试过使用lambda函数,但我无法通过第一个示例。所以我可以在括号之间使用任意数量的参数?是的,你可以捕获多个变量。我知道下界函数,但我没有想过这样使用它。事后来看,当字符串使用字典顺序进行比较时,使用它来搜索前缀是非常有意义的。非常感谢你!您不需要这样复杂的检查,若向量已排序,则下界将返回正确的迭代器或Dictionary.end。所以你只需要比较迭代器不,你必须检查。下界返回排序向量中插入项的位置。您考虑的是std::binary_搜索,它返回true或false。b不匹配,但迭代器返回mate。我知道下界函数,但我没有想过这样使用它。事后来看,当字符串使用字典顺序进行比较时,使用它来搜索前缀是非常有意义的。非常感谢你!您不需要这样复杂的检查,若向量已排序,则下界将返回正确的迭代器或Dictionary.end。所以你只需要比较迭代器不,你必须检查。下界返回排序向量中插入项的位置。您考虑的是std::binary_搜索,它返回true或false。b不匹配,但迭代器返回mate。