我想创建一个,以便我可以使用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;
}
但我更喜欢使用标准库函数来实现它。
答案 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;
}