c++计数和映射

C++ count and map

本文关键字:映射 c++      更新时间:2023-10-16

我正在计算每个单词在文本文件中出现的次数。我想避免情况,因此我对我的输入做了以下处理,然后再计数。我有一个map数据结构,有字符串和int来保存计数。现在,当我输出这个单词和它的计数时,我不希望这个单词是小写的,而是希望它保持原来的形式。因此,为了计数,所有的单词都应该改为小写,但在输出时,它们都应该是原来的大小写。是否有办法只用一张地图就能做到这一点?

std::map的第三个模板参数为比较器类型。您可以提供自己的比较操作,在您的例子中是大小写不敏感的操作。

struct CaseInsensitive {
  bool operator()(std::string const& left, std::string const& right) const {
    size_t const size = std::min(left.size(), right.size());
    for (size_t i = 0; i != size; ++i) {
      char const lowerLeft = std::tolower(left[i]);
      char const lowerRight = std::tolower(right[i]);
      if (lowerLeft < lowerRight) { return true; }
      if (lowerLeft > lowerRight) { return false; }
      // if equal? continue!
    }
    // same prefix? then we compare the length
    return left.size() < right.size();
  }
};

然后实例化你的map:

typedef std::map<std::string, unsigned, CaseInsensitive> MyWordCountingMap;

注意:只保留第一个拼写(这似乎对您没有问题)

应该可以。对于多种情况,第一个大小写将在地图内部,而不是小写。此外,该解决方案只使用您想要的一个映射

using namespace std;
struct StrCaseInsensitive
{
    bool operator() (const string& left , const string& right )
    {
        return _stricmp( left.c_str() , right.c_str() ) < 0;
    }
};
int main(void)
{
    char* input[] = { "Foo" , "bar" , "Bar" , "FOO" };
    std::map<string, int , StrCaseInsensitive> CountMap;
    for( int i = 0 ; i < 4; ++i )
    {
        CountMap[ input[i] ] += 1;
    }
    return 0;
}

您可以使用map<string, vector<string> >

键是小写的单词。该值是该单词的所有给定大小写的向量。

(你也可以使用multimap<string, string>,这基本上是相同的,但我通常更喜欢向量的映射)

 map<string, vector<string> > m;
 m.size(); // number of lowercase words
 m["abc"].size(); // number of the given cases of the word "abc"

对于同一个单词的不同大小写变体,您希望发生什么?

一种可能性是使用std::multiset和无大小写比较器作为其Compare模板参数。在这种情况下,每个单词的所有变体都将保存在集合中。每个单词的出现次数可以通过集合的count()成员函数获得。

您可以使用结构体或std::pair来保留原始情况和出现的次数。你的字体看起来像这样:map < string, pair <string, int> >