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