Chapter05 Exercise5-2, 5-3, 5-4

ドウモデス。
掃除ついでに,キーボードを外に持って行って,エアーダスターかましたら,
一見それほど汚れていなかったキーボードから,かなりほこりがでてきちゃいました。
ワタシが使っているのは,Happy Hacking Keyboard Lite なんですが,
ほこりをとって綺麗になったせいか,スコスコ感がまして,打鍵の際の音が静かになりました。
やったぜ!
あと,だいぶ前に,左シフトがうるさくてたまらんかったので,キートップの中に付いている
金具をはずしたら,静かになってくれた。
頑張って金貯めて,HHK Proを買いたい。何の話だ?

Exercise 5-2

テストしてないが,たぶん大丈夫。

// list version
list<Student_info> extract_fails(list<Student_info>& students)
{
  list<Student_info> fail;

  for (list<Student_info>::iterator iter = students.begin(); iter != students.end(); ) {
    if (fgrade(*iter)) {
      fail.push_back(*iter);
      iter = students.erase(iter);
    } else {
      ++iter;
    }
  }

  return fail;
}

// vector version
vector<Student_info> extract_fails(vector<Student_info>& students)
{
  vector<Student_info> fail;

  for (vector<Student_info>::iterator iter = students.begin(); iter != students.end(); ) {
    if (fgrade(*iter)) {
      fail.push_back(*iter);
      iter = students.erase(iter);
    } else {
      ++iter;
    }
  }

  return fail;
}

Exercise 5-3

変更部分を抜粋。
正解じゃない気がする。
つかうコンテナによって,typedef しなきゃならない,つまり,

typedef std::vector<Student_info> Student_container;
typedef std::list<Student_info> Student_container;

とは書けないので,この解答では問題がある気がする。
まぁ,わからんのでギブ。

  • Student_info.hh
// For ex5-3
typedef std::vector<Student_info> Student_container;
Student_container extract_fails(Student_container& students);
  • Student_info.cc
#include <stdexcept>

bool fgrade(const Student_info& s)
{
  double g = 0;
  try {
    g = grade(s);
  }
  catch (std::domain_error e) {
    g = grade(s.midterm, s.final, 0);
  }
  return g < 60;
}

istream& read(istream& is, Student_info& s)
{
  is >> s.name >> s.midterm >> s.final;
  read_hw(is, s.homework);
  try {
    s.final_grade = grade(s);
  }
  catch (std::domain_error e) {
    s.final_grade = grade(s.midterm, s.final, 0);
  }
  return is;
}

Student_container extract_fails(Student_container& students)
{
  Student_container fail;

  Student_container::iterator iter = students.begin();
  while (iter != students.end()) {
    if (fgrade(*iter)) {
      fail.push_back(*iter);
      iter = students.erase(iter);
    }
    else {
      ++iter;
    }
  }
  return fail;
}
  • ex5-3.cc

デモ用。ifstream使っているのは,リダイレクトでファイルを渡していたのですが,
SEGVって,原因がわからんからgdbで追おうと思ったけど,ググってみたら,
どうやら,cygwingdbでは,実行時にリダイレクトできないっぽいので,
わざわざifstreamを使うに至った次第。

#include <iostream>
#include <fstream>
#include <algorithm>
#include <cassert>

#include "Student_info.hh"
#include "grade.hh"

using namespace std;

int main()
{
  Student_container students;
  Student_info record;
  ifstream fin("grades.txt");
  assert(fin);

  while (read(fin, record)) {
    students.push_back(record);
  }

  sort(students.begin(), students.end(), compare);
  Student_container fails = extract_fails(students);
  cout << "====================Passed====================" << endl;
  for (Student_container::const_iterator iter = students.begin(); iter != students.end(); ++iter) {
    cout << iter->name << ", " << iter->final_grade << endl;
  }

  cout << "====================Failed====================: " << endl;
  for (Student_container::const_iterator iter = fails.begin(); iter != fails.end(); ++iter) {
    cout << iter->name << ", " << iter->final_grade << endl;
  }

  return 0;
}
  • grades.txt
Moo 100 100 100 100 100 100 100 100
Moore 75 85 77 59 0 85 75 89
Norman 57 78 73 66 78 70 88 89
Olson 89 86 70 90 55 73 80 84
Peerson 47 70 82 73 50 87 73 71

Fail1 45 55 65 80 90 70 65 60
Russel 72 87 88 54 55 82 69 87
Thomas 90 96 99 99 100 81 97 97
Vaughn 81 97 99 67 40 90 70 96
Westerly 43 98 96 79 100 82 97 96


Baker 67 72 73 40 0 78 55 70
Davis 77 70 82 65 70 77 83 81
Edwards 77 72 73 80 90 93 75 90
Franklin 47 70 82 73 50 87 73 71

Jones 77 82 83 50 10 88 65 80
Harris 97 90 92 95 100 87 93 91
Smith 87 92 93 60 0 98 75 90
Carpenter 47 90 92 73 100 87 93 91

Fail2 55 55 65 50 55 60 65 60
  • 実行結果
% ./ex5-3
====================Passed====================
Baker, 67.2
Carpenter, 82
Davis, 75
Edwards, 78.2
Franklin, 66.6
Harris, 92.4
Jones, 77.2
Moo, 100
Moore, 79.4
Norman, 72.8
Olson, 82.8
Peerson, 66.6
Russel, 79.4
Smith, 87.2
Thomas, 95.6
Vaughn, 87
Westerly, 86.2
====================Failed====================: 
Fail1, 58
Fail2, 57

Exercise 5-4

何言っているか,ワタシには理解できんですたい。
おそらくですが,typedef 使っているので,
list と vector の違いを宣言だけにしろ,みたいなことだと思う。


ほいで,上記の ex5-3.cc には,list も vector も登場していないので,
ま,見えないだけだけど,そうなので,大丈夫なんじゃね?

まとめ

この辺のExerciseが,テンプレートへの布石になっているのかなぁと。
template とかすれば,listやvectorの違いを意識しないで済むだろうと,
たぶんそういう風に持って行きたいのではないかと思われます。