[英]C++: Find a char in a string, then find another char following previous char
首先道歉,如果标题有点含糊。 我是C ++的新手,并且仍在尝试理解该语言的复杂性。
基本上,我正在处理大量单词(实际上是词典),这些单词已存储在向量中。
我对此的思考过程是,我想找到所有带有“ c”的单词。 每次在其中带有“ c”的单词时,请查看其后是否带有“ h”。 如果确实如此,则将单词假掉。 希望得到像这样的词:
-carbon
-carry
etc etc
到目前为止,我已经尝试实现一些代码,而这是到目前为止的内容:
bool hasCWithNoH(string wordName)
{
if (wordName.find('c'))
{
if (wordName.find('ch'))
{
return false;
}
}
}
这在主{}源文件中由此被调用:
void findCWithNoH()
{
cout << "List of words found with a 'c' but with no following 'h': " << endl;
for (Word word : words)
{
string testWord = word.getName();
if (word.hasCWithNoH(testWord))
{
cout << testWord << endl;
}
}
}
结果是这样的:
czarowitz
czech
czechic
czechoslovakian
czechs
h
ha
haaf
haak
haar
habeas-corpus
habenaria
结果发现每个单词都以“ c”和“ h”开头(不是我想要的)。
我认为我没有正确使用find()函数和循环,请问关于如何设置该函数以及find()函数是否正确使用的一些建议?
如果需要更多说明,请发表评论,我可以进一步阐述。
注意事项 :
假设所有出现的“ c”后面都不应有“ h”,这应该可以工作。
当不存在c时,您不会返回false请检查string :: find返回值
返回值第一个匹配项的第一个字符的位置。 如果未找到匹配项,则该函数返回string :: npos。
将功能更改为
bool hasCWithNoH(string &wordName)
{
if (wordName.find('c')!=string::npos)
{
if (wordName.find("ch")!=string::npos)//Also use double quotes for string "ch"
{
return false;
}
else
{
return true;
}
}
else
{
return false; //Because word does not contain c.
}
}
有两个问题:
正确的功能应为:
bool hasCWithNoH(string wordName) {
if (wordName.find("c") != string::npos) {
if (wordName.find("ch") != string::npos) {
return false;
} else {
return true;
}
} else {
return false;
}
}
编辑:最佳答案表明几乎相同的代码更改,同时提供了更好的解释,因此我在此进行更新并提供不同的内容。
我们注意到该程序称为string :: find两次-意味着每个字符串都被扫描了两次。 我们可以保存一张通行证吗? 当然。
让我们首先设置测试程序。 我们有测试数据和预期结果。 如果实际结果有所不同,程序将输出实际结果并说“失败”。
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
bool hasCWithNoH(const string& wordName) {
return true;
}
int main() {
string words[] = { // test data
"czarowitz",
"czech",
"czechic",
"czechoslovakian",
"czechs",
"h",
"ha",
"haaf",
"haak",
"haar",
"habeas - corpus",
"habenaria"
};
string expect_result[] = {
"czarowitz",
"habeas - corpus"
};
vector<string> actual_result;
for (string word : words) {
if (hasCWithNoH(word)) {
actual_result.push_back(word);
}
}
if (actual_result.size() == 2 &&
equal(expect_result, expect_result + 2, actual_result.begin())) {
cout << "Test passed" << endl;
} else {
cout << "Test failed, the following words are returned:" << endl;
for_each(actual_result.begin(), actual_result.end(), [](const string& e) { std::cout << e << endl; });
}
return 0;
}
使用虚拟功能肯定可以使测试用例失败。
如果我们将功能更改为上述答案中的一项,则测试将通过。
现在让我们实现一遍功能。 从描述,以及所提供的测试数据,我们知道函数应该返回true
只有在下列条件:
因此功能可能是:
bool hasCWithNoH(const string& wordName) { // use reference type wherever possible
bool match = false; // By default, it doesn't match
for (string::const_iterator it = wordName.begin(); it != wordName.end(); ++it) {
if (*it == 'c') {
match = true; // If we see there's a 'c', it becomes a candidate...
if (it != (wordName.end() - 1) && *(it + 1) == 'h') {
match = false;
break; // But if later we see an 'h' right behind 'c', it's rejected immediately
}
}
}
return match;
}
现在,案件再次通过。
为了改进,我们注意到该函数仅接受std :: string。 最好不要依赖某些数据类型。 例如,如果调用方具有C样式的字符串,则在调用该函数之前,不应该强迫他将其转换为std :: string。 因此我们可以使用模板函数:
template <class Iterator>
bool hasCWithNoH(Iterator first, Iterator last) {
bool match = false;
for (Iterator it = first; it != last; ++it) {
if (*it == 'c') {
match = true;
if (it != last - 1 && *(it + 1) == 'h') {
match = false;
break;
}
}
}
return match;
}
请注意,现在它要求我们以以下方式调用该函数:
//...
for (string word : words) {
if (hasCWithNoH(word.begin(), word.end())) {
actual_result.push_back(word);
}
}
//...
运行程序,我们看到测试用例再次通过。
小优化:无需进行其他查找,只需检查下一个字符:
bool hasCWithNoH(const string & wordName)
{
size_t pos = wordName.find('c');
if ( pos == string::npos )
return false;
while ( pos !=string::npos )
{
if ( pos +1 < wordName.size() ) {
if ( wordName[pos+1] == 'h' )
return false;
}
else
return true;
pos = wordName.find('c', pos+1);
}
return true;
}
假设您需要: 每次在其中带有'c'的单词时,请查看其后是否带有'h'。 如果确实如此,则将单词假为假
由于您恰好在h
之后需要c
,因此可以使用:
if( string[ string.find_first_of( 'c' ) + 1 ] == 'h' ){
return false;
} else {
return true;
}
注意:
如果存在多个c
即使其他c
具有h
也为字符串返回true
。 像: "abc_ch"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.