C++ 检查字符串是否包含多个单词的最快/最简单方法
我使用的是c++11,可以使用正则表达式。我想知道检查一个字符串是否包含多个单词的最快方法是什么,如果是,检查有多少个。本例中的单词定义为由空格分隔的字符组 我有几个选择:C++ 检查字符串是否包含多个单词的最快/最简单方法,c++,string,C++,String,我使用的是c++11,可以使用正则表达式。我想知道检查一个字符串是否包含多个单词的最快方法是什么,如果是,检查有多少个。本例中的单词定义为由空格分隔的字符组 我有几个选择: 按空格拆分字符串,计算拆分长度 使用某种正则表达式 计算空白字符数 选项1是最简单的方法,但考虑多个空格字符会使拆分更加复杂。2可能会慢一些,我不知道如何从中计数。3是我能想到的最快的,但是可能有很多角落的情况需要考虑。我希望我的解决方案尽可能高效,并且包含尽可能少的额外库。这对我来说是一个可以解决的问题,但我需要更多的洞察
我倾向于第一种,但是什么功能最好呢
istringstream
加上一个迭代器,stringstream
,一些char*
magic?我不确定最快的方法是什么。我会遍历字符串,计算单词数并遍历任何连续的空格
- 当从空白移动到非空白时,增加字数
- 如果字符串以非空白开头,则增加字数
int countWords(string& toCount, const string& whitespace){ enum countStatus { startOfString, initialWhitespace, movePastWord, movePastWhitespace } status=startOfString; int wordCount=0; for(char& c : toCount) { bool characterIsWhitespace=false; if (whitespace.find(c)!=string::npos) { characterIsWhitespace=true; } switch(status) { case startOfString: if (characterIsWhitespace) { status=initialWhitespace; } else { status=movePastWord; wordCount++; } break; case initialWhitespace: if (!characterIsWhitespace) { wordCount++; status=movePastWord; } break; case movePastWord: if (characterIsWhitespace) { status=movePastWhitespace; } break; case movePastWhitespace: if (!characterIsWhitespace) { wordCount++; status=movePastWord; } } } return wordCount; }
std::map
。在下面的代码中,您可以计算文本中出现了多少个单词
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
int main()
{
std::map<std::string,int> strCount;
std::string str("AA BB ABC AA GE AAf FF JJ BB CC ");
std::string temp;
// Split String Based on Whitespace (i.e. you need to modify it to suit the text format you have. )
for ( int i(0); i < str.size(); ++i ){
temp += str[i];
if ( str[i] == ' ' ){
temp.pop_back();
++strCount[temp]; // <-- if element new, insert it in map and associate new counter, otherwise increment counter of element.
temp.clear();
}
}
std::map<std::string,int>::const_iterator iter;
for( iter = strCount.begin(); iter != strCount.end(); iter++ ) {
std::cout << "#: " << iter->second << " string: " << iter->first << std::endl;
}
return 0;
}
最好的解决方案是最适合您需要的。您需要它快速,还是易于阅读/维护?你可以把这三个词都写下来,在它们上面运行基准测试,看看你更喜欢使用哪一个。@FrançoisAndrieux我补充了一点说明。如果你想在字符串中找到类似的词,我认为你必须将每个词存储在向量中,而不是排序。在这种情况下,相似的单词将在序列中逐个定位。这里你得到了下一个复杂性O(NlogN)+O(N)(排序+检查向量中的每个元素)。这不是一个大问题,可能值得做一些实验,它将帮助你学习基准代码。这不是你需要一直做的事情,但这很适合。对于您的情况,任何不分配内存的东西(例如计数)都有可能比分配内存的东西更快。我本来会发布所有的代码,包括int main()等,但我花了更长的时间来努力让#include正确格式化,而不是编写这个方法。
#: 2 string: AA
#: 1 string: AAf
#: 1 string: ABC
#: 2 string: BB
#: 1 string: CC
#: 1 string: FF
#: 1 string: GE
#: 1 string: JJ