我有字符串"Dog is a kind of animal"
;
现在如果我必须找到一个包含任何这些单词的字符串而不是像Cat,Horse,Tiger,Lion这样的狗,那么我必须给出字符串状态OK。
我完全了解string.find
函数,它将单个子字符串与字符串匹配。但在我的情况下,我必须检查30种可能性的字符串,如猫,马,狮子...... 30种动物。
我不知道如何继续这样做。
string line2 = "horse is a kind of animal" ;
const char* array[] = { "cat", "dog", "horse" };
for (unsigned int i = 0; i<= sizeof(array); i++)
{
size_t loc = line2.find( array[i], 0);
if( loc != string::npos)
{
std::cout <<"true"<<std::endl;
break;
}// end if
else
{
cout <<"not found"<< std::endl;
}
答案 0 :(得分:3)
考虑使用众多可用正则表达式(例如google re2)库中的一个来搜索搜索词的并集 - 例如(cat|dog|horse|...)
。这应该比简单地搜索每个子串更快,因为它只需要扫描一次字符串。
答案 1 :(得分:1)
这是一个非常直接的方法(我将添加替代品):
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
string victim = "horse is a kind of animal" ;
vector<string> targets;
targets.push_back("cat");
targets.push_back("dog");
targets.push_back("horse");
string found_target; // set to the target we found, if we found any
for( vector<string>::const_iterator it = targets.begin(); found_target.empty() && (it != targets.end()); ++it )
{
if( victim.find(*it) != string::npos )
found_target = *it;
}
if( !found_target.empty() )
cout << "Found '" << found_target << "'\n";
else
cout << "Not found\n";
}
如果你有C ++ 0x编译器的好处,你可以使用lambda来使代码更清洁:
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
string victim = "horse is a kind of animal" ;
vector<string> targets;
targets.push_back("cat");
targets.push_back("dog");
targets.push_back("horse");
vector<string>::const_iterator it_found = find_if(targets.begin(), targets.end(), [&victim](string s) -> bool {
return( victim.find(s) != string::npos );
});
if( it_found != targets.end() )
cout << "Found '" << *it_found << "'\n";
else
cout << "Not found\n";
}
答案 2 :(得分:0)
这里有很多因素,例如:
最灵活的方法是使用正则表达式。 Boost有一个实现,许多流行的操作系统(例如Linux man regexp等)也是如此。检查匹配“^([AZ] +)\ s +是\ s + a \ s + kind \ s + of \ s + animal \ s $”,其中带括号的子表达式(动物的类型)可以通过regexp库提取,然后在数组中搜索。您可能希望使用字符串不敏感的比较。这假定在运行时从某些外部源读取支持的动物列表。正如bdonlan建议的那样 - 如果事先已知,你可以在正则表达式(dog|cat|...)
中对其进行硬编码。
你可以对数组进行预排序并使用二进制搜索:C ++的STL已经有了排序和搜索的算法。这比使用动物列表填充std::set
要快一些,但是你可能不关心速度差异。
另一种方法是使用C ++流进行扫描:
std::string what, is, a, kind, of, animal;
char unwanted;
std::istringstream input(" Dog is a kind of animal");
if ((input >> what >> is >> a >> kind >> of >> animal) &&
!(input >> unwanted) &&
is == "is" && a == "a" && kind == "kind" && of == "of" && animal == "animal")
{
// match!
}
你可以用sscanf做类似的事情,这需要注意指针而不是读取太多字符,但也更有效:
char what[21];
if (sscanf(candidate, "%.20[A-Za-z] is a kind of animal %c", what, &unwanted) == 1)
// match...
答案 3 :(得分:0)
这是我的回复,它忽略奖励积分的情况!
帮助获取数组的大小:
template <typename T, std::size_t N>
inline std::size_t sizeof_array(T(&)[N]) {
return N;
}
测试有效字符串的代码:
std::string text = "Dog is a kind of animal";
std::string animals[] = {"dog","cat","lion","giraffe"};
std::transform(text.begin(), text.end(), text.begin(), ::tolower);
bool valid = false;
for(size_t i = 0; !valid && i < sizeof_array(animals); ++i) {
valid = (text.find(animals[i]) != std::string::npos);
}
答案 4 :(得分:0)
您可以使用TR1正则表达式。这个简单的示例使用带有布尔结果的搜索。还有其他功能可以让您迭代多个匹配或进行搜索和替换。
#include <iostream>
#include <regex>
#include <string>
int main()
{
std::string line("horse is a kind of animal");
std::regex rx("cat|dog|horse");
if (std::regex_search(line.begin(), line.end(), rx))
std::cout << "true\n";
else
std::cout << "not found\n";
}
答案 5 :(得分:0)
如果你可以使用c ++ STL, 创建一个以关键字作为元素的集合。
std :: set myset; myset.insert( “狗”); myset.insert( “猫”); ......
然后从该行中提取候选令牌 并检查它是否存在于集合中:
myset.count(token)//如果匹配则为1,如果不匹配则为0