《accelerated c++》第四章练习

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();
}
时间: 2024-10-13 16:37:29

《accelerated c++》第四章练习的相关文章

第四章

第四章 源代码的下载和编译 1.下载.编译和测试Android源代码 配置Android源代码的下载环境 ①创建一个存放下载脚本文件(repo)的目录 # mkdir  ~/bin # PATH=~/bin:$PATH ②下载repo脚本文件 # curi http://dl-ssl.google.com/dl/googlesource/git-repo/repo > -/bin/repo # chmod a+x ~/bin/repo ③创建存放Android源代码的目录 # mkdir and

《UML精粹》 第四章 时序图

第四章 时序图 一般来说,我们会在一张时序图中画出某个情节的相关行为,图种会秀出这个使用案例(use case)里面可能出现的一些对象,以及在对象间传送的信息. 本章将通过一个简单情节,做时序图各方面的相关讨论.假设我们现在有一份订单,并且准备调用它的一个命令,算出这份订单的价格.为了达到这个目的,订单需要产看它里面所拥有的一些订单明细.决定它们的价格,价格决定方式是以订单明细中所包含产品之定价规则为基础决定的.对所有订单明细做完上述动作之后,接下来订单要算出整个折扣,这时候它是以跟客户绑在一起

Java 线程第三版 第四章 Thread Notification 读书笔记

一.等待与通知 public final void wait() throws InterruptedException 等待条件的发生. public final void wait(long timeout) throws InterruptedException 等待条件的发生.如果通知没有在timeout指定的时间内发生,它还是会返回. public final void wait(long timeout, int nanos) throws InterruptedException

2017.06.29数据挖掘基础概念第四章

第四章39.为什么在进行联机分析处理(OLAP)时,我们需要一个独立的数据仓库,而不是直接在日常操作的数据库上进行 1.提高两个系统的性能 2.操作数据库支持多事务的并发处理,需要并发控制和恢复机制,确保一致性和事务的鲁棒性 3.两者有着不同的数据的结构.内容和用法40.什么是数据仓库 数据仓库是一种数据库,它与单位的操作数据库分别维护,数据仓库系统允许将各种应用系统集成在一起,为统一的历史数据分析提供坚实的平台,对信息处理提供支持,是一个面向主题的.集成的.时变得.非易失的数据集合,支持管理者

构建之法学习(第四章 两人合作)

第四章 两人合作 1.代码规范  1)代码风格规范.主要是文字上的规定,看似表面文章,实际上非常重要. *原则:简明,易读,无二义性 *缩进:4个空格 *行宽:行宽必须限制,可以限定为100字符 *括号:在复杂的条件表达式中,用括号清除地表示逻辑优先级 *断行与空白的{}行:推荐格式如下 if ( condition ) {        DoSomething(); } else {       DoSomethingElse(); } *分行:不要把多条语句放在一行上.并且,不要把多个变量定

第四章—变量,作用域和内存问题(二)

第四章-变量,作用域和内存问题(二) JS没有块级作用域 js没有块级作用域,这个概念容易导致误解,这里就区分下几个情况,大家好好参考下: 我们知道,在其他类C的语言中,由花挂号封闭的代码块都有自己的作用域.但是在JS中,却没有块级作用域: 这里if(true){}代表条件永真,永远执行这条.if(false){}的话就是永远不执行这条. 这个代码执行之后,在if语句定义的变量,在if语句外可以访问的到.在if语句中的变量声明会将变量添加到当前的执行环境中(这里是全局环境). 还有如下的两个例子

Shell脚本学习指南 [ 第三、四章 ] 查找与替换、文本处理工具

摘要:第三章讨论的是编写Shell脚本时经常用到的两个基本操作.第四章总共介绍了约30种处理文本文件的好用工具. 第三章 查找与替换 概括:本章讨论的是编写Shell脚本时经常用到的两个基本操作:文本查找.文本替换. 3.1  查找文本 如需从输入的数据文件中取出特定的文本行,主要的工具为grep程序.POSIX采用三种不同grep变体:grep.egrep.fgrep整合为单个版本,通过不同的选项,分别提供这三种行为模式.who | grep -F root上面使用-F选项,以查找固定字符串r

javascript高级程序设计 第十四章--表单脚本

javascript高级程序设计 第十四章--表单脚本 在HTML中表单由<form>元素表示,在js中表单对应的是HTMLFormElement类型,这个类型也有很多属性和方法:取得表单元素的引用还是为它添加id特性,用DOM操作来获取表单元素:提交表单:把<input>或<button>元素的type特性设置为"submit",图像按钮把<input>元素的type特性设置为"image",也可以调用submit(

Java语言程序设计(基础篇) 第四章 数学函数、字符和字符串

第四章 数学函数.字符和字符串 4.2 常用数学函数 方法分三类:三角函数方法(trigonometric method).指数函数方法(exponent method)和服务方法(service method) 4.4 String类型 String类型不是基本类型,而是引用类型(reference type).

linux第四章实验报告

Linux第四章 用户和文件权限管理 实验环境 公司的linux主机即将提供给技术部作为开发服务器使用,根据部门内项目组的构成情况,首先需要建立相应的组账号.用户账号,并作为目录设置权限,还需要设置一个共用的数据存储目录,便于同事之间的数据交换. 需求描述 1.建立用户目录 创建目录/tech/benet和/tech/accp,分别用于存放各项目组中用户账号的宿主文件夹.例如,kylin用户的宿主目录应位于/tech/benet/kylin. 2.添加组账户 为两个项目组添加组账号benet,a