C ++:C字符串集

时间:2010-12-25 14:47:46

标签: c++ string set

我想创建一个,以便我可以使用set :: find

检查某个单词是否在集合中

但是,C字符串是指针,因此默认情况下,集合会将它们与指针值进行比较。要正常运行,必须取消引用它们并比较字符串。

我可以将构造函数作为比较器传递给strcmp()函数,但这并不是我想要它的工作方式。我可能要检查的单词可能是更长字符串的一部分,我不想因为性能问题而创建新字符串。如果没有集合,我会使用strncmp(a1,a2,3)来检查前3个字母。事实上,3可能是最长的,所以我可以将第三个参数保持不变。

有没有办法构建一个通过调用strncmp()来比较其元素的集合?我们非常感谢代码示例。

这是我想要做的伪代码:

bool WordInSet (string, set, length)
{
   for (each word in set)
    {
       if strncmp(string, word, length) == 0
            return true;
    }
    return false;
}

但我更喜欢使用标准库函数来实现它。

3 个答案:

答案 0 :(得分:6)

您可以创建比较器函数对象。

struct set_object {
    bool operator()(const char* first, const char* second) {
        return strncmp(first, second, 3);
    }
};

std::set<const char*, set_object> c_string_set;

然而,制作一组std::strings

会更容易,更可靠

答案 1 :(得分:2)

制作包装函数:

bool myCompare(const char * lhs, const char * rhs)
{
    return strncmp(lhs, rhs, 3) < 0;
}

答案 2 :(得分:0)

假设一个恒定值,因为单词长度看起来像是在向我提出麻烦。我建议不要这个解决方案。

看:strcmp解决方案不适合您,因为它将const char*参数视为以空字符结尾的字符串。您需要一个完全相同的函数,但将参数视为单词 - 这将转换为“any-not-a-letter” -terminated string。

可以通用方式将strcmp定义为:

template<typename EndPredicate>
int generic_strcmp(const char* s1, const char* s2) {
    char c1;
    char c2;
    do { 
        c1 = *s1++; 
        c2 = *s2++; 
        if (EndPredicate(c1)) {
            return c1 - c2; 
        }
    } while (c1 == c2);

    return c1 - c2; 
}

如果EndPredicate是一个返回true的函数,如果它的参数等于\0,那么我们得到一个常规的strcmp来比较0终止的字符串。

但是为了有一个比较单词的函数,唯一需要的变化就是谓词。使用isalpha头文件中的反向<cctype>函数就足以表明当遇到非字母字符时字符串结束。

因此,在您的情况下,该集合的比较器将如下所示:

#include <cctype>

int wordcmp(const char* s1, const char* s2) {
    char c1;
    char c2;
    do { 
        c1 = *s1++; 
        c2 = *s2++; 
        if (!isalpha(c1)) {
            return c1 - c2; 
        }
    } while (c1 == c2);

    return c1 - c2; 
}