码迷,mamicode.com
首页 > 编程语言 > 详细

《accelerated c++》第四章练习

时间:2016-07-10 11:06:47      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

4-0本章程序

//4.1 计算一位同学的分数
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <stdexcept>

using namespace std;

double median(vector<double> vec);
double grade(double midterm,double terminal,double homework);
double grade(double midterm, double terminal, const vector<double>&hw);
istream& read_hw(istream& in, vector<double>& hw);

int main()
{
    cout << "please enter your first name: ";
    string name;
    cin >> name;
    cout << "hello, " << name << "!" << endl;

    cout << "please enter your midterm and terminal grades: ";
    double midterm, terminal;
    cin >> midterm >> terminal;
    cout << "enter all your homework grades: "
        << "followed by end-of-file: ";
    vector<double>homework;
    read_hw(cin, homework);
    try{
        double final_grade = grade(midterm,terminal, homework);
        streamsize prec = cout.precision();
        cout << "your final grade is: " << setprecision(3)
            << final_grade << setprecision(prec) << endl;
    }
    catch (domain_error){
        cout << endl << "you must enter your grades: "
            "please enter again." << endl;
        return 1;
    }
    return 0;
}

double median(vector<double> vec)
{
    typedef vector<double>::size_type vec_sz;
    vec_sz size = vec.size();
    vec_sz mid = size / 2;
    if (size == 0){
        throw domain_error("median of an empty vector");
    }
    sort(vec.begin(), vec.end());
    return size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
}

double grade(double midterm, double terminal, double homework)
{
    return midterm*0.2 + terminal*0.4 + homework*0.4;
}

double grade(double midterm, double terminal, const vector<double>&hw)
{
    if (hw.size() == 0)
        throw domain_error("no homework! ");
    return grade(midterm, terminal, median(hw));
}

istream& read_hw(istream& in, vector<double>& hw)
{
    if (in){
        hw.clear();
        double x;
        while (in >> x){
            hw.push_back(x);
        }
        in.clear();
    }
    return in;
}
//4.2 计算多位同学的成绩

//median.h
#ifndef _MEDIAN_H_
#define _MEDIAN_H_

#include <vector>
double median(std::vector<double>);
#endif

//median.c
#include <algorithm>
#include <stdexcept>
#include "median.h"

using namespace std;

double median(vector<double> vec)
{
    typedef vector<double>::size_type vec_sz;
    vec_sz size = vec.size();
    vec_sz mid = size / 2;
    if (size == 0){
        throw domain_error("median of an empty vector");
    }
    sort(vec.begin(), vec.end());
    return size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
}

//student_info.h
#ifndef _STUDENT_INFO_H
#define _STUDENT_INFO_H

#include <string>
#include <vector>
#include <iostream>

struct student{
    std::string name;
    double midterm, terminal;
    std::vector<double> homework;
};

bool campare(const student&, const student&);
std::istream& read(std::istream&, student&);
std::istream& read_hw(std::istream&,std::vector<double>&);
#endif

//student_info.c
#include "student_info.h"

using namespace std;

bool campare(const student& x, const student& y)
{
    return x.name < y.name;
}

std::istream& read(std::istream& is, student& s)
{
    is >> s.name >> s.midterm >> s.terminal;
    read_hw(is, s.homework);
    return is;
}

std::istream& read_hw(std::istream& is, std::vector<double>& hw)
{
    if (is){
        hw.clear();
        double x;
        while (is >> x){
            hw.push_back(x);
        }
        is.clear();
    }
    return is;
}

//grade.h
#ifndef _GRADE_H
#define _GRADE_H

#include <vector>
#include "student_info.h"

double grade(double, double, double);
double grade(double, double, std::vector<double>&);
double grade(const student&);
#endif

//grade.c
#include <stdexcept>
#include "grade.h"
#include "median.h"

using namespace std;

double grade(double midterm, double terminal, double homework)
{
    return midterm*0.2 + terminal*0.4 + homework*0.4;
}

double grade(double midterm, double terminal, const vector<double>&hw)
{
    if (hw.size() == 0)
        throw domain_error("no homework! ");
    return grade(midterm, terminal, median(hw));
}

double grade(const student& s)
{
    return grade(s.midterm, s.terminal,s.homework);
}

//main.c
#include <algorithm>
#include <iomanip>
#include <stdexcept>
#include "student_info.h"
#include "grade.h"

using namespace std;

int main()
{
    vector<student> students;
    student record;
    string::size_type maxlen = 0;
    while (read(cin, record)){
        maxlen = max(maxlen, record.name.size());
        students.push_back(record);
    }
    sort(students.begin(), students.end(), campare);

    for (vector<student>::size_type i = 0; i != students.size(); ++i){
        cout << students[i].name
            << string(maxlen + 1 - students[i].name.size(),  );
        try{
            double final_grade = grade(students[i]);
            streamsize prec = cout.precision();
            cout << setprecision(3) << final_grade
                << setprecision(prec);
        }
        catch (domain_error e){
            cout << e.what();
        }
        cout << endl;
    }
    return 0;
}

关于read_hw函数的解释:


std::istream& read_hw(std::istream& is, std::vector<double>& hw)
{
    if (is){
        hw.clear();
        double x;
        while (is >> x){
            hw.push_back(x);
        }
        is.clear();
    }
    return is;
}

首先两个参数都是传址调用,原因是输入流不能复制,只能用引用,而后面那个vector是我们要改变的值,所以要用引用;

if(is)的意思是判断流读取是否成功,如书中所受,当读入文件结束符,或者输入不兼容的值,或硬件问题会导致读取失败;

hw.clear()是清空vector<double>的值,使之为空向量;

is.clear()是重置流,作用是为了继续接收其他流格式,在read函数里的string name等等;


 

4-1max函数需要匹配,将

int maxlen改为string::size_type maxlen即可


 

4-2写一个程序,计算从1到100的所有整数的平方。程序输出两列:

第一列是1到100的整数值,第二列是整数值的平方。

使用setw函数来控制输出,使得这些值按列整齐排列。

#include <iostream>
#include <iomanip>

using namespace std; 

int main()
{
    int count = 101;
    for (int i = 1; i != count; i++){
        cout <<left<< setw(3) << i << " "
            << i*i << endl;
    }
    return 0;
}

4-3如果我们上面的程序,计算从1到999的值的平方,但是没有改变setw的参数,

会发生什么呢?重写这个程序,使它更为灵活,在增加i的时候i的时候,不需要修改setw的参数。

(求出数字的位数)

#include <iostream>
#include <iomanip>

using namespace std; 

int number(int );

int main()
{
    int count = 115;
    int num = number(count - 1);
    cout << num << endl;
    for (int i = 1; i != count; i++){
        cout<<left<< setw(num) << i << " "
            << i*i << endl;
    }
    return 0;
}

int number(int x)
{
    int num = 1;
    while(x / 10 > 0){
        num++;
        x = x / 10;
    }
    return num;
}

4-4改变你的平方程序,使用double类型取代int类型,使用控制符来控制输出,使得这些值按列整齐输出

#include <iostream>
#include <iomanip>

using namespace std;

int digital(double);

int main()
{
    double count = 99;
    for (double i = 0; i < count; i += 0.5)
    {
        cout << left << setw(digital(count) + 2) << i
            <<i*i<< endl;
    }
    return 0;
}

int digital(double x)
{
    int count = 1;
    int integer = x / 1;

    while (integer != 0){
        count++;
        integer /= 10;
    }
    return count;
}

本来想用digital连同算出整数位加上小数位,思路是,把小数位分离出来,计算后乘以10移到整数位再减去整数位,

但是出现了问题,小数的加减乘除似乎不是那么精确和简单,所以最后采用保留两位小数的方法。

在网上看到其他求数位的方法:(用log10求数位)

 

#include <cmath>
#include <iomanip>
#include <iostream>

using namespace std;

int get_width(double n) {
  return log10(n) + 1;
}

int main() {
  double max = 1000.0;
  
  for (double i = 1.0; i <= max; ++i) {
    cout << setw(get_width(max))
     << i
     << setw(get_width(max * max) + 1)
     << i * i
     << endl;
  }
  
  return 0;
}

 


 

4-5写一个函数,从输入流中读取单词,并把单词保存在一个vector中,然后使用这个函数写一个程序,计算

输入中单词的数目,并计算 每个单词出现的次数(计算单词出现次数参考第三章练习)

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>

using namespace std;

int count(istream& , vector<string>&);
int frequency(vector<string>&,vector<string>&);

int main()
{
    cout << "please input the text: " << endl;
    vector<string> text;
    int number;
    number = count(cin, text);

    vector<string> temp;
    cout << "this text has " << number << " words" << endl;

    frequency(text, temp);
    int count;
    for (int i = 0; i != temp.size(); i++){
        count = 0;
        for (int j = 0; j != text.size(); j++){
            if (temp[i] == text[j]){
                count++;
            }
        }
        cout << "the word: " << temp[i] << " "
            << count << " times" << endl;
    }
    
    return 0;
}

int count(istream& in, vector<string>& text)
{
    int num = 0;
    if (in){
        text.clear();
        string word;
        while (in >> word){
            text.push_back(word);
            num++;
        }
        in.clear();
    }
    return num;
}

int frequency(vector<string>&text, vector<string>&temp)
{
    int i, j;
    for (i = 0; i != text.size(); i++){
        for (j = 0;; j++){
            if (j == temp.size()){
                temp.push_back(text[i]);
                break;
            }
            else{
                if (temp[j] == text[i])
                    break;
            }
        }
    }
    return 1;
}

4-6重写student_info结构来直接计算成绩,并且在student_info结构中只保存最终成绩

//median.h and median.c needn‘t change

//student_info.h has change struct student:
struct student{
    std::string name;
    double final_grade;
};

//student_info.c  has change the function of read
std::istream& read(std::istream& is, student& s)
{
    double midterm, terminal;
    is >> s.name >> midterm >> terminal;

    vector<double>homework;
    read_hw(is, homework);

    if (is)
        s.final_grade = grade(midterm, terminal, homework);

    return is;
}

//grade.h has no change and grade.c change last function
double grade(student& s)
{
    return s.final_grade;
}

//main.c
#include <algorithm>
#include <iomanip>
#include <stdexcept>
#include "student_info.h"
#include "grade.h"

using namespace std;

int main()
{
    vector<student> students;
    student record;
    string::size_type maxlen = 0;
    while (read(cin, record)){
        maxlen = max(maxlen, record.name.size());
        students.push_back(record);
    }
    sort(students.begin(), students.end(), campare);

    for (vector<student>::size_type i = 0; i != students.size(); ++i){
        cout << students[i].name
            << string(maxlen + 1 - students[i].name.size(),  );
        try{
            streamsize prec = cout.precision();
            cout << setprecision(3) << students[i].final_grade
                << setprecision(prec);
        }
        catch (domain_error e){
            cout << e.what();
        }
        cout << endl;
    }
    return 0;
}

4-7写一个程序计算保存在vector<double>对象中的数值的平均值

#include <iostream>
#include <vector>

using namespace std;

double average(vector<double> );

int main()
{
    vector<double> vec;
    double x;
    while (cin >> x){
        vec.push_back(x);
    }

    cout << "the average is :" <<
        average(vec)<<endl;
}

double average(vector<double> vec)
{
    if (vec.size() == 0)
        throw domain_error("the vector is empty!");
    double sum = 0;
    for (vector<double>::size_type i = 0; i != vec.size(); i++){
        sum += vec[i];
    }
    return sum / vec.size();
}

 

《accelerated c++》第四章练习

标签:

原文地址:http://www.cnblogs.com/monster-prince/p/5657242.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!