在给定字符串向量(按长度排序)的情况下,用于查找等长度字符串范围的惯用C++

Idiomatic C++ for finding a range of equal length strings, given a vector of strings (ordered by length)

本文关键字:字符串 用于 查找 范围 C++ 向量 排序 情况下      更新时间:2023-10-16

给定一个std::vector< std::string >,向量是按字符串长度排序的,如何找到长度相等的强度范围?

我期待着用C++编写一个惯用的解决方案。

我找到了这个解决方案:

// any idea for a better name? (English is not my mother tongue)
bool less_length( const std::string& lhs, const std::string& rhs )
{
    return lhs.length() < rhs.length();
}
std::vector< std::string > words;
words.push_back("ape");
words.push_back("cat");
words.push_back("dog");
words.push_back("camel");
size_t length = 3;
// this will give a range from "ape" to "dog" (included):
std::equal_range( words.begin(), words.end(), std::string( length, 'a' ), less_length );

有标准的方法(漂亮地)做到这一点吗?

我希望您可以编写如下比较器:

struct LengthComparator {
    bool operator()(const std::string &lhs, std::string::size_type rhs) {
        return lhs.size() < rhs;
    }
    bool operator()(std::string::size_type lhs, const std::string &rhs) {
        return lhs < rhs.size();
    }
    bool operator()(const std::string &lhs, const std::string &rhs) {
        return lhs.size() < rhs.size();
    }
};

然后使用它:

std::equal_range(words.begin(), words.end(), length, LengthComparator());

我预计operator()的第三个过载永远不会被使用,因为它提供的信息是多余的。范围必须预先排序,因此算法比较范围中的两个项目没有意义,它应该将范围中的项目与您提供的目标进行比较。但标准并不能保证这一点。[编辑:定义这三个意味着您可以使用相同的比较器类将矢量按顺序放在第一位,这可能很方便]。

这对我有效(gcc 4.3.4),虽然我认为这对您的实现也有效,但我不太确定它是否真的有效。它实现了equal_range的描述所说的对结果正确的比较,并且25.3.3/1不要求模板参数T必须与迭代器引用的对象的类型完全相同。但我可能错过了一些添加了更多限制的文本,所以在将其用于任何重要内容之前,我会进行更多标准的搜索。

您的方法肯定不是单一的,但必须构造一个具有目标长度的伪字符串看起来不太优雅,也不太可读。

我可能会编写自己的助手函数(即string_length_range),通过字符串列表封装一个简单明了的循环。没有必要对任何事情都使用std::工具。

std::equal_range执行二进制搜索。这意味着words向量必须排序,在这种情况下,这意味着它的长度必须不递减。

我认为你的解决方案是一个很好的解决方案,肯定比编写自己的二进制搜索实现要好,因为二进制搜索是出了名的容易出错,很难证明是正确的。

如果你无意进行二进制搜索,那么我同意Alexander的观点。简单的for循环单词是最干净的。