| AcceleratedC++/Chapter5 | AcceleratedC++/Chapter7 |
Contents
|
~cpp ret.insert(ret.end(), bottom,begin(), bottom.end());
~cpp copy(bottom.begin(), bottom.end(), back_inserter(ret));
~cpp copy(bottom.begin(), bottom.end(), ret.end());
~cpp
vector<string> split(const string& str)
{
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while(i != str.end()) {
i = find_if(i, str.end(), not_space); // 공백이 아닌 부분을 찾고
iter j = find_if(i, str.end(), space); // 공백인 부분을 찾아서
if(i != str.end())
ret.push_back(string(i,j)); // 그만큼의 문자열엘 벡터에 넣음
i = j;
}
return ret;
}
~cpp
bool isPalindrome(const string& s)
{
return equal(s.begin(), s.end(), s.rbegin());
}
~cpp #ifndef GUARD_urls_h #define GUARD_urls_h #include <vector> #include <string> std::vector<std::string> find_urls(const std::string& s); #endif
~cpp
#include <algorithm>
#include <cctype>
#include <string>
#include <vector>
#include "urls.h"
using std::find;
using std::find_if;
using std::isalnum;
using std::isalpha;
using std::isdigit;
using std::search;
using std::string;
using std::vector;
bool not_url_char(char);
string::const_iterator url_end(string::const_iterator, string::const_iterator);
string::const_iterator url_beg(string::const_iterator, string::const_iterator);
vector<string> find_urls(const string& s)
{
vector<string> ret;
typedef string::const_iterator iter;
iter b = s.begin(), e = s.end();
// look through the entire input
while (b != e) {
// look for one or more letters followed by `://'
b = url_beg(b, e);
// if we found it
if (b != e) {
// get the rest of the \s-1URL\s0
iter after = url_end(b, e);
// remember the \s-1URL\s0
ret.push_back(string(b, after));
// advance `b' and check for more \s-1URL\s0s on this line
b = after;
}
}
return ret;
}
string::const_iterator url_end(string::const_iterator b, string::const_iterator e)
{
return find_if(b, e, not_url_char);
}
// find_if 함수의 테스팅에 이용되는 함수이다. char은 string 의 iterator의 값이다.
bool not_url_char(char c)
{
// characters, in addition to alphanumerics, that can appear in a \s-1URL\s0
static const string url_ch = "~;/?:@=&$-_.+!*'(),";
// see whether `c' can appear in a \s-1URL\s0 and return the negative
return !(isalnum(c) ||
find(url_ch.begin(), url_ch.end(), c) != url_ch.end());
}
//이 예제의 핵심 함수이다.
string::const_iterator url_beg(string::const_iterator b, string::const_iterator e)
{
/*
b 는 protocol type의 시작위치를 가르키게된다.
i 는 :// 의 시작 위치를 가리키는 역할을 한다.
e 는 url의 마지막 텍스트를 가리키는 역할을 한다.
*/
static const string sep = "://";
typedef string::const_iterator iter;
// `i' marks where the separator was found
iter i = b;
// string 에서 sep 의 문자열의 시작부분을 찾아서 i에 iterator를 대입한 후 e와 비교하여
// 같지 않으면 실행한다. (즉, sep를 찾았을 경우)
while ((i = search(i, e, sep.begin(), sep.end())) != e) {
// make sure the separator isn't at the beginning or end of the line
if (i != b && i + sep.size() != e) {
// `beg' marks the beginning of the protocol-name
iter beg = i;
while (beg != b && isalpha(beg[-1]))
--beg; //protocol-typed의 위치에 존재하는 문자열이 조건에 맞을 경우 앞으로 한칸씩 움직이면서 검사한다.
// is there at least one appropriate character before and after the separator?
if (beg != i && !not_url_char(i[sep.size()]))
return beg;
}
// the separator we found wasn't part of a \s-1URL\s0; advance `i' past this separator
i += sep.size();
}
return e;
}
~cpp
bool did_all_hw(const Student_info& s)
{
return ((find(s.homework.begin(), s.homework.end(), 0)) ==
s.homework.end());
}
find함수는 처음두개의 전달인자 범위에서 세번째 전달인자의 값을 찾지 못하면 2번째 전달인자를 리턴한다. (찾으면 첫번째전달인자 ~cpp
vector<Student_info> did, didnt;
// read the student records and partition them
Student_info student;
while (read(cin, student)) {
if (did_all_hw(student))
did.push_back(student);
else
didnt.push_back(student);
}
// verify that the analyses will show us something
if (did.empty()) {
cout << "No student did all the homework!" << endl;
return 1;
}
if (didnt.empty()) {
cout << "Every student did all the homework!" << endl;
return 1;
}
empty멤버함수: 컨테이너가 비어 있으면 true, 아니면 false리턴~cpp
// 이 함수는 제대로 동작하지 않습니다.
double median_anlysis(const vector<Strudent_info>& students)
{
vector<double> grades;
transform(students.begin(), students.end(),
back_inserter(grades), grade);
return median(grades);
}
transform함수: 처음2개의 전달인자 범의의 값들을 4번째함수에 대입 리턴값을 3번째 주소부터 넣음(?)~cpp
double grade_aux(const Student_info& s)
{
try{
return grade(s);
} catch(domain_error) {
return grade(s.midterm, s.final, 0);
}
}
~cpp
double median_anlysis(const vector<Strudent_info>& students)
{
vector<double> grades;
transform(students.begin(), students.end(),
back_inserter(grades), grade_aux); //grade를 grade_aux로 수정
return median(grades);
}
~cpp
void write_analysis(ostream& out, const string& name,
double analysis(const vector<Student_info>&),
const vector<Student_infor>& did,
const vector<Student_infor>& didnt)
{
cout << name << ": median(did) = " << analysis(did) <<
", median(didnt) = " << analysis(didnt) << endl;
}
~cpp
int main()
{
// students who did and didn't do all their homework
vector<Student_info> did, didnt;
// read the student records and partition them
Student_info student;
while (read(cin, student)) {
if (did_all_hw(student))
did.push_back(student);
else
didnt.push_back(student);
}
// verify that the analyses will show us something
if (did.empty()) {
cout << "No student did all the homework!" << endl;
return 1;
}
if (didnt.empty()) {
cout << "Every student did all the homework!" << endl;
return 1;
}
// do the analyses
write_analysis(cout, "median", median_analysis, did, didnt);
write_analysis(cout, "average", average_analysis, did, didnt);
write_analysis(cout, "median of homework turned in",
optimistic_median_analysis, did, didnt);
return 0;
}
~cpp
double average(const vector<double>& v)
{
return accumulate(v.begin(), v.end(), 0.0) / v.size();
}
accumulate함수: 처음2개의 전달인자를 3번째 전달인자에 누적시킴(주의 0.0대신 0을 사용하면 정수로 인식 소수점 부분을 버려버림)~cpp
double average_grade(const Student_info& s)
{
return grade(s.midterm, s.final, average(s.homework));
}
~cpp
double average_analysis(const vector<Student_info>& students)
{
vector<double> grades;
transform(students.begin(), students.end(),
back_inserter(gardes), aveage_grade);
return median(grades);
}
~cpp
// s의 0이 아닌 요소들의 중앙 값, 만약 0이 아닌 요소가 하나도 없다면 결과는 0이 됩니다.
double optimistic_median(const Student_info& s)
{
vector<double> nonzero;
remove_copy(s.homework.begin(), s.homework.end(),
back_inserter(nonzero), 0);
if(nozero.empty())
return grade(s.midterm, s.final, 0);
else
return grade(s.midterm, s.final, median(nonzero));
}
~cpp
vector<Student_info> extract_fails(vector<Student_info>& students){
vector<Student_info> fail;
remove_copy_if(student.begin(), stduents.end(),
back_inserter(fail), pgrade);
students.erase(remove_if(studens.begin(), students.end(),
fgrade), stduents.end());
return fail;
}
remove_copy_if함수: 처음 2개의 전달인자 범의의값들을 4번째 전달인자 함수를 만족하지 않는 함수만 3번째 전달인자에 복사~cpp
bool pgrade(const Student_info& s)
{
return !fgrade(s);
}
fgrade함수를 반전시킨 함수~cpp
vector<Student_info> extract_fails(vector<Student_info>& students)
{
vector<Student_info>::iterator iter =
stable_partition(students.begin(), students.end9), pgrade);
vector<Student_info> fail(iter, stduents.end());
students.erase(iter, students.end());
return fail;
}
stable_partition, partition 차이점?? 순서를 안바꾸다니?? @,.@~cpp v.erase(remove_if(students.begin(), students.end(), fgrade), students.end());