登場した単語の回数を数える

Perlとかの本の最初に出てきそうなやつですね。文字列からMeCabでsplitしていたりする付近は違うけど。C++でRubyとかPerlとかのsplitは付属していないんですか><。

#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <mecab.h>

using namespace std;

vector<string> split(string, string);

int main (int argc, char **argv) 
{
  char input[1024] = "太郎は次郎が持っている本を花子に渡した。花子と太郎。日本語ああああ日本語日本語日本語日本語";

  MeCab::Tagger *tagger = MeCab::createTagger( "" );
  const MeCab::Node *node = tagger->parseToNode( input );

  map<string, int> freq;
  map<string, int>::iterator it;

  for( node=node->next; node->next; node=node->next ){ 
	vector<string> strvec = split( node->feature, "," );
	if (strvec[0] == "名詞"){
	  string noun = strvec[6];
	  it = freq.find(noun);
	  if (it != freq.end()){
		it->second += 1;
	  }else{
		freq.insert(pair<string, int>(noun, 1));
	  }
	}
  } 
  it = freq.begin();
  while( it != freq.end() ){
	cout << (*it).first << " : " << (*it).second << endl;
	++it;
  }
  
  delete tagger;
  return 0;
}

vector<string> split(string s, string c){
  vector<string> ret;
  for( int i=0, n; i <= s.length(); i=n+1 ){
	n = s.find_first_of( c, i );
	if( n == string::npos ) n = s.length();
	string tmp = s.substr( i, n-i );
	ret.push_back(tmp);
  }
  return ret;
}

MeCabの解析の結果から名詞だけを取り出す方法とかが分からなかったので、解析の結果を「,」で区切って、ごにょごにょしている。名詞の位置が7番目のフィールドとかに勝手に書き変えられているのはなんでだろう。。。

/Users/yasuhisa/cpp% ./mecab
太郎 : 2 : 1
日本語 : 5 : 1
次郎 : 1 : 1
花子 : 1

よしよし。