raulyo 2009. 7. 16. 11:09

연습문제
3-3 입력으로 문장을 읽어들여, 각각의 단어들이 몇 번씩 나타나는지 계산하는 프로그램을 작성해보세요

// chapter3-3.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <vector>
#include <map>
#include <string>

using std::cout; using std::cin;
using std::endl; using std::string;
using std::vector; using std::cerr;
using std::map; using std::domain_error;

void tokenizer(vector<string>& result, string context, char token);
void tokenizer(map<string,int>& result, string context, char token);

int _tmain(int argc, _TCHAR* argv[])
{
 string content;
 vector<string> v_content;
 map<string,int> m_content;
 cout << "please enter the content:";
 
 getline(cin,content,'\n'); //getline(cin,content); #include <string>
 tokenizer(m_content,content,' ');
 tokenizer(v_content,content,' ');

/*
 vector<string>::iterator pos;
 for(pos = v_content.begin();pos != v_content.end(); ++pos)
 {
  cout << *pos << "라는 단어가 총 ";
  unsigned int n = 0;
  int count  = 0;
  while(n < v_content.size())
  {
   if(*pos == v_content[n++])
     count++;
  }
  cout << count << "개 있습니다." <<endl;
 }
*/
 map<string,int>::iterator m_pos;
 for(m_pos = m_content.begin();m_pos != m_content.end(); ++m_pos)
 {
  cout << m_pos->first << "라는 단어가 총 " << m_pos->second << "개 있습니다." <<endl;
 }
 return 0;
}
// 문장으로 들어온 string 값을 토큰으로 구분시켜서
// 단어별로 vector에 담아준다.   예외는 domain_error 발생
// ex) hi seo hi seo std
//        vector[0] = "hi"; vector[1] = "seo"; vector[2] = "hi"; vector[3] = "seo"; vector[4] = "std";
       
void tokenizer(vector<string>& result, string context, char token)
{
 if(context.empty()) //들어온 context값이 비었을때 예외발생
  throw domain_error("string context empty!!");

 string::size_type begin = 0 , end = context.size(); //context값의 begin값과 end값 설정
 while(begin < end)  //begin값부터 end값까지 반복한다.
 {
  string::size_type index = context.find(token,begin); //token을 context에서 찾아서 해당인덱스반환
     string word = context.substr(begin,(index-begin));  //해당인덱스까지 단어를 뽑아낸다.
     result.push_back(word);  //해당 단어를 map에 저장
    if(index == string::npos) //검색함수가 실패했을때 string::npos를 반환한다.
      break;
    begin = index + 1;
 }
}
// 문장으로 들어온 string 값을 토큰으로 구분시켜서
// 단어별로 map에 갯수랑 담아준다.  예외는 domain_error 발생
// ex) hi seo hi seo std
//        map["hi"] = 3; map["seo"] = 2; map["std"] = 1;

void tokenizer(map<string,int>& result, string context, char token)
{
 if(context.empty()) //들어온 context값이 비었을때 예외발생
  throw domain_error("string context empty!!");

 string::size_type begin = 0 , end = context.length(); //context값의 begin값과 end값 설정
 while(begin < end) //begin값부터 end값까지 반복한다.
 {
  string::size_type index = context.find(token,begin); //token을 context에서 찾아서 해당인덱스반환
  string word = context.substr(begin,(index-begin));  //해당인덱스까지 단어를 뽑아낸다.
  if(result.size() == 0) //맵데이타가 비었을때
  { 
    result.insert(make_pair(word,1));
  }
  else
  {
       map<string,int>::iterator find_pos = result.find(word);  //해당되는 단어가 원래 있다면

     if(find_pos != result.end()) //있다면 갯수증가
          find_pos->second++;
     else //없다면 해당단어 추가
      result.insert(make_pair(word,1));
  }
 
  if(index == string::npos) //검색함수가 실패했을때 string::npos를 반환한다.
   break;
  begin = index + 1;
 }
}