42-1-마.count

반복자 구간에서 지정한 값과 일치하는 요소의 개수를 센다. 값을 취하는 버전과 조건자를 취하는 버전이 각각 따로 정의되어 있다.

 

size_t count(InIt first, InIt last, const T& val);

size_t count_if(InIt first, InIt last, UniPred F);

 

리턴값은 조건을 만족하는 요소의 개수이며 일치하는 요소가 없으면 0이 리턴된다. 다음 예제는 노래 가사 문자열에서 a문자의 출현 회수를 센다.

 

: count

#include <iostream>

#include <algorithm>

using namespace std;

 

void main()

{

     const char *str="Oh baby baby,How was I supposed to know "

          "That something wasn't right here";

     size_t num;

 

     num=count(&str[0],&str[strlen(str)+1],'a');

     printf("이 문장에는 a가 %d개 있습니다.\n",num);

}

 

count는 반복자 구간을 차례대로 순회하면서 매 요소가 val과 같은지 == 연산으로 비교하여 일치하는 요소가 발견될 때마다 회수를 1 증가시키고 순회를 마칠 때 조사한 회수를 리턴한다. 위 문자열에는 a가 모두 5개 있으므로 count의 실행 결과는 5가 될 것이다. count는 == 연산으로 일치 조건을 판단하지만 count_if는 단항 조건자 객체가 일치 조건을 판단하므로 좀 더 다양한 조건을 점검할 수 있다.

 

: count_if

#include <iostream>

#include <algorithm>

#include <functional>

using namespace std;

 

void main()

{

     const char *str="Oh baby baby,How was I supposed to know "

          "That something wasn't right here";

     size_t num;

 

     num=count_if(&str[0],&str[strlen(str)+1],bind2nd(greater<char>(),'t'));

     printf("이 문장에는 t보다 더 큰 문자가 %d개 있습니다.\n",num);

}

 

이항 조건자인 greater의 두 번째 인수를 bind2nd 어댑터로 't'로 고정하여 't'보다 큰 문자의 개수를 세어 보았다. 결과는 7이다. 다음 예제는 C의 난수 발생기 성능을 테스트하는데 0~10까지의 난수를 무작위로 2000개 만들어 골고루 잘 나왔는지 점검한다.

 

: count2

#include <Turboc.h>

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

 

const int NUM=2000;

const int RANGE=10;

 

void makerand(int &i)

{

     i=rand()%RANGE;

}

 

void main()

{

     vector<int> num(NUM);

     vector<int>::iterator it;

     int i;

 

     randomize();

     for_each(num.begin(),num.end(),makerand);

     for (i=0;i<RANGE;i++) {

          printf("%02d의 출현 회수 : %d\n",i,count(num.begin(),num.end(),i));

     }

}

 

NUM 크기의 벡터를 선언하고 for_each문으로 벡터의 각 요소에 RANGE 미만의 난수를 생성하여 채워 넣었다. for_each가 레퍼런스를 전달받으면 요소값을 변경할 수도 있다. 벡터를 초기화한 후 난수들이 몇 개씩 생성되었는지 count 함수로 세어 보았다. 실행 결과는 다음과 같다.

 

00의 출현 회수 : 215

01의 출현 회수 : 200

02의 출현 회수 : 193

03의 출현 회수 : 183

04의 출현 회수 : 205

05의 출현 회수 : 207

06의 출현 회수 : 191

07의 출현 회수 : 214

08의 출현 회수 : 191

09의 출현 회수 : 201

 

대체로 200 전후의 회수로 생성되었는데 골고루 난수들이 잘 생성되었음을 확인할 수 있다. 각각의 수에 대한 출현 빈도를 함수 호출 하나로 구할 수 있다는 면에서 간편하기는 하지만 사실상의 이중 루프라 C로 문제를 직접 푸는 것보다 성능은 다소 느리다.