确定给定句子是不是包含给定单词c ++ [关闭]
Posted
技术标签:
【中文标题】确定给定句子是不是包含给定单词c ++ [关闭]【英文标题】:determining whether the given sentence contain the given word or not c++ [closed]确定给定句子是否包含给定单词c ++ [关闭] 【发布时间】:2014-06-23 10:24:34 【问题描述】:我需要确定在 c++ 中是否在另一个字符串中找到给定的单词。
我的函数原型会像bool check(string sentence, string word);
而“句子”可能是:word.someWord AND/OR/XOR word2.someWord *AND/OR/XOR* word3.someWord
,然后就是这样。
举个真实的例子:unlock_the_door.value=1 AND turn_of_car.checkSum=1
现在,在这个例子中,如果我将 word 分配给 lock,我的 check 函数应该返回 false,但如果我将它赋予“unlock”,它应该返回 true。
为此,我习惯使用 .find() 函数,但大家都知道这是错误的,因为即使我将 lock 作为单词参数,它也会返回 true,因为“unlock”包含“lock”
我想我需要使用正则表达式,但我不知道该怎么做。有没有人可以帮助我?提前致谢。
【问题讨论】:
请问-1是什么原因? 您不是在提出尝试的解决方案并提出问题;您正在提出一个解决方案并要求 SO 为您实施它(至少,在我看来,这就是它的样子)。在您可以使用基于正则表达式的实现之前,您应该至少了解 一些 正则表达式语法;否则,您获得的任何解决方案都可能对您不可用(或可用但非常脆弱)。无论哪种方式,您是在询问 C++ 正则表达式 API、要使用的实际正则表达式语法还是其他什么? @utnapistim 实际上我需要知道有没有办法在不使用正则表达式的情况下做到这一点 有;您可以标记字符串并处理每个标记(参见@SteveBarnes 的回答),您可以为缓冲区编写一个有状态的前向解析器(作为 FSM 实现 - 更高效但更复杂/容易出错),您可以使用正则表达式(高抽象级别)或以上的组合。 我会使用一个组合:首先将表达式标记为术语(“unlock_the_door.value=1”、“AND”、“turn_of_car.checkSum=1”),然后在标识符上应用正则表达式每个条款。它不是最有效的,但它很好地分离了关注点,并且以后易于更改/扩展。 (如果您必须在要求非常苛刻的环境中执行此操作,请考虑编写每个字符的单通解析器(作为 FSM)。 【参考方案1】:首先将您的句子分成单词,然后检查列表以查看它是否包含您要查找的确切单词。
您还可以考虑使用正则表达式并查找您的单词,每个单词前面都有任何行开头或空格,后面是空格、标点符号或行尾。
【讨论】:
@Steve_Barnes 感谢您的回复,如果我将句子分成单词,对于上面的示例,它将类似于 word1=unlock_tw_door.value=1 word2=And word3=turn_of_car.checkSum=1 并再次找到由于 word1 包含锁定词,因此函数将为锁定词返回 true。 A 期望您匹配 列表中的单词,而不是在列表中的单词上使用 find。 “解锁”!=“锁定”【参考方案2】:我的意思是下划线是空格。
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <iterator>
#include <algorithm>
bool check( const std::string &sentence, const std::string &word )
std::istringstream is( sentence );
return std::find( std::istream_iterator<std::string>( is ),
std::istream_iterator<std::string>(),
word ) != std::istream_iterator<std::string>();
int main()
std::cout << std::boolalpha
<< check( "unlock the door.value=1 AND turn of car.checkSum=1", "lock" )
<< std::endl;
std::cout << std::boolalpha
<< check( "unlock the door.value=1 AND turn of car.checkSum=1", "unlock" )
<< std::endl;
return 0;
输出是
false
true
如果下划线不是空格,那么您可以使用相同的std::istringstream
和标准函数std::getline
并检查每个读取的字符串是否等于给定的字符串。
或者您确实可以使用成员函数find_first_of
将句子拆分为std::vector<std::string>
类型的对象
例如
#include <iostream>
#include <iomanip>
#include <string>
bool check( const std::string &sentence, const std::string &word )
const char *delimiters = " _=.";
std::string::size_type first, last;
bool found = false;
first = 0;
while ( !found && first != std::string::npos )
first = sentence.find_first_not_of( delimiters, first );
if ( first != std::string::npos )
last = sentence.find_first_of( delimiters, first );
found = sentence.substr( first, last == std::string::npos ? last : last - first ) == word;
first = last;
return found;
int main()
std::string s = "unlock_the_door.value=1 AND turn_of_car.checkSum=1";
std::cout << std::boolalpha
<< check( s, "lock" )
<< std::endl;
std::cout << std::boolalpha
<< check( s, "unlock" )
<< std::endl;
return 0;
输出是
false
true
【讨论】:
@Vlad_from_Moscow 下划线不是空格,它们是单词的一部分。但是我不能你的建议你可以根据它编辑它吗? @eday 查看我更新的帖子。【参考方案3】:您可以使用 C++11 regex_search
作为搜索模式,使用单词边界 (\b
) 或下划线包围您的单词。
#include <iostream>
#include <string>
using namespace std;
bool check(const string &sentence, const string &word)
string boundary = "(_|\\b)";
return regex_search(sentence, regex(boundary + word + boundary));
int main ()
string sentence = "unlock_the_door.value=1 AND turn_of_car.checkSum=1";
cout << check(sentence, "lock") << endl;
cout << check(sentence, "unlock") << endl;
如果您不想使用 C++11 或者您正在使用不支持 C++11 正则表达式的编译器(例如 4.9.0 之前的 gcc 版本),您可以使用 Boost library。您只需要下载库并将这两行添加到您的源代码中:
#include <boost/regex.hpp>
using namespace boost;
还记得将选项 -lboost_regex
传递给 gcc。
【讨论】:
【参考方案4】:用下划线作为分隔符来分割句子。 并使用 stricmp 函数。 应该可以解决了。
【讨论】:
我猜你不明白我的问题所以请不要推它【参考方案5】:如果我猜对了,你想看看这个词是否不仅包含在句子中,还包含在这个句子中的单词中。 你可以这样做:
bool check (std::string sentence, std::string word)
std::string part;
for(unsigned int ii=0; ii<sentence.size()-word.size(); ii++)
part = sentence.substr(ii,word.size());
if(!part.compare(word))
return true;
return false;
这会检查句子中长度为 word.size() 的每个部分是否等于单词。如果等于 this 将返回 true,否则返回 false。
好吧,我之前写的可能正是你不想要的。如果您只想与句子中的单词进行比较(无论您是什么单词,您都必须考虑分隔符),那么您可以这样做(您需要包含 string.h):
bool check (std::string sentence, std::string word)
char *c_str_sentence = new char[sentence.size()+1]; //you need this cause string.c_str() will return const char* but strtok needs char*;
char *c_str_word = new char[word.size()+1];
strcpy(c_str_sentence,sentence.c_str());
strcpy(c_str_word,word.c_str());
bool is_contained = false;
const char *delimiters = " _=."; //any delimiter you wish;
char *part = strtok(c_str_sentence,delimiters);
while (part != NULL)
if(!strcmp(part,c_str_word))
is_contained = true;
break;
part = strtok(NULL,delimiters);
delete[] c_str_sentence;
delete[] c_str_word;
return is_contained;
仅当您检查“解锁”而不是“锁定”时才返回 true。但是,通过指定分隔符,您可以指定您希望将哪些内容视为单词,哪些内容不视为。
【讨论】:
你的第二个函数每次调用都会泄漏内存。它使用new[]
分配内存并且从不使用delete[]
释放它。以上是关于确定给定句子是不是包含给定单词c ++ [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
2021-10-16:单词拆分 II。给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
给定一个单词之间有多个空格的句子。删除多余的空格,使句子在单词之间只有一个空格[重复]