Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 检查字符串是否包含多个单词的最快/最简单方法_C++_String - Fatal编程技术网

C++ 检查字符串是否包含多个单词的最快/最简单方法

C++ 检查字符串是否包含多个单词的最快/最简单方法,c++,string,C++,String,我使用的是c++11,可以使用正则表达式。我想知道检查一个字符串是否包含多个单词的最快方法是什么,如果是,检查有多少个。本例中的单词定义为由空格分隔的字符组 我有几个选择: 按空格拆分字符串,计算拆分长度 使用某种正则表达式 计算空白字符数 选项1是最简单的方法,但考虑多个空格字符会使拆分更加复杂。2可能会慢一些,我不知道如何从中计数。3是我能想到的最快的,但是可能有很多角落的情况需要考虑。我希望我的解决方案尽可能高效,并且包含尽可能少的额外库。这对我来说是一个可以解决的问题,但我需要更多的洞察

我使用的是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;
      }
      

    在此场景中,您可以使用关联容器。C++有多种选择。例如,您可以利用
    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