C++第二次作业(Accelerated C++第四章)



(一)最长的、最短的字符串

编写一个程序用于报告它的输入中最长以及最短的字符串的长度

/*
3-4
编写一个程序用于报告它的输入中最长以及最短的字符串的长度
*/
#include 
#include 
#include 
#include 
#include 
using namespace std;
int main()
{
	string str;
	cout << "please input a string by the end of EOF  " << endl;
	cin >> str;
	int maxx = str.size();
	int minn = str.size();
	string str1 = str, str2 = str;
	while (cin >> str)
	{
		if (str.size() > maxx)
			maxx = str.size(), str2 = str;
		else if (str.size() < minn)
			minn = str.size(), str1 = str;
	}
	cout << "the smallest string is " << str1;
	cout << "  whose length is "<< minn << endl;
	cout << "the largest string is " << str2;
	cout << "  whose length is " << maxx << endl;

	system("pause");
	return 0;
}



(二)单词计数


P75
4-5
用一个函数读入单词放在向量中,
利用这个函数写一个程序计算输入的单词数和每个单词出现的次数

/*
P75
4-5
用一个函数读入单词放在向量中,
利用这个函数写一个程序计算输入的单词数和每个单词出现的次数
*/

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
//http://bbs.csdn.net/topics/340078578

void getString(vector &vec)
{
	string str;
	while (cin >> str)
	{
		vec.push_back(str);
	}
}

int main()
{
	string str;
	vector  vec;
	int cnt = 0;
	getString(vec);
	sort(vec.begin(), vec.end());
	vector::iterator it = vec.begin();
	for (; it != vec.end();)
	{
		cnt = 1;
		str = *it++;
		while (str == *it)
		{
			it++;
			cnt++;
			if (it == vec.end())
				break;
		}
		cout << " 字符串为 " << str << "的次数为" << cnt << endl;
	}

	cout << endl << "最终输入个数为 " << vec.size() << endl;
	system("pause");
	return 0;
}



(三)计算平方

题意描述:

提示用户输入一个整数 I,编写一个程序来计算从1~I 的双精度浮点数(double)值的平方。程序的输出分为两列:第一列是double值,第二列是double值的平方。使用控制器来控制输出,让数值按左对齐排列起来。注意,程序应当有一定灵活性,当 I 增大时我们不需要修正setw的参数。

提示:可以先完成练习4-2,4-3以资借鉴。

 

//1-100整数值的平方 (4-2)

法一

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
//1-100整数值的平方
int main()
{
	for (int i = 1; i <= 100; i++)
	{
		cout.width(4);
		cout << i;
		cout.width(8);
		cout << i*i;
		cout << endl;
		//cout << setw(4) << i << setw(8) << i*i << endl;
	}
	system("pause");
	return 0;
}

法二

int main()
{
	for (int i = 1; i <= 100; i++)
	{
		cout << setw(4) << i << setw(8) << i*i << endl;
	}
	system("pause");
	return 0;
}




//1-999整数值的平方,要求更有适应性,当改变最大值时,不用改参数 (4-3)

//1-999整数的平方,不能修改setw参数的值
#include #include #include #include //setw using namespace std; const int maxn = 1000; int getWidth(int n) { return log10(n) + 1; } int main() { for (int i = 1; i <= maxn; i++) { cout << setw(getWidth(maxn)) << i << setw(getWidth(maxn*maxn)+1) << i*i << endl; } system("pause"); return 0; }
C++第二次作业(Accelerated C++第四章)_第1张图片


补充:

1、setw(n)返回一个streamsize的值,如果把这个值用于输出流s,那么它的作用跟调用s.width(n)效果一样.

2、setw的头文件是



//最终--------计算double的平方

第二列的话,如果直接左对齐,因为中间没有分隔开,所以只能是与自己左边的数相差一个空格
所以还是要右对齐,但是他的间距要设置多少这里比较难想到。。。
getWidth(mm*mm)是最大那个的,所有数要跟他对齐,同时要结合这一行左边的数和右边的数,所以就有:
setw((getWidth(mm*mm)-getWidth(i)+getWidth(i*i) -1))


/*
输入一个数i
计算从1到i的double的平方
输出: 用控制器,左对齐
PS:   程序的灵活性,当i增大时不需修正setw的参数

可以先完成4-2   4-3作为借鉴
*/
//计算从1到I的双精度浮点数的平方
#include 
#include 
#include 
#include 

using namespace std;
int getWidth(double n) //求double型的长度
{
	return log10(n) + 1;
}
int main()
{
	cout << "请输入一个数i: ";
	double mm;
	cin >> mm;
	for (double i = 1; i <= mm; i++)
	{
		streamsize prec = cout.precision();//记录一开始的精度

		cout << setw(getWidth(mm)*(-1)) << i;
		//第一列直接左对齐就行了
		cout << setw((getWidth(mm*mm)-getWidth(i)+getWidth(i*i) -1)) << i*i;
		//第二列的话,如果直接左对齐,因为中间没有分隔开,所以只能是与自己左边的数相差一个空格
		//所以还是要右对齐,但是他的间距要设置多少这里比较难想到。。。
		//getWidth(mm*mm)是最大那个的,所有数要跟他对齐,同时要结合这一行左边的数和右边的数,所以就有:
		//setw((getWidth(mm*mm)-getWidth(i)+getWidth(i*i) -1))
		cout << endl;
	}
	system("pause");
	return 0;
}



C++第二次作业(Accelerated C++第四章)_第2张图片


C++第二次作业(Accelerated C++第四章)_第3张图片





(四)多个学生的成绩

题意描述:练习4-0,练习4-6。

也就是说,首先,务必看懂4.5节的程序,弄清楚每个函数的来龙去脉,作用何在。然后,将Student_info 结构体的定义改写为:

Student_info{string name, double finalGrade}

其中 finalGrade 代表最终成绩。根据这个变化,相应的修改4.5节的程序,完成同样的功能。




(这个写了好久啊、、、、一个多小时。。。。我要去吃饭了。。。2016/10/7/17:46)

第一个方案(没有改结构体前的)

引用三个头文件median.h; student_info.h; grade.h

(注意:#pragma once的作用是使得这个头文件只被编译一次,跟P69讲的那个差不多 )


//median.h

#pragma once
//median.h
/*
查找中值
不要用using namespace std;
因为在头文件中使用这个的话,引用这个头文件就默认也使用了这句话。
*/
#include 
#include  //domain_error
#include 
using std::sort;
using std::domain_error;
using std::vector;
//查找中值
double median(vector vec)
{
	typedef vector::size_type vec_sz;
	vec_sz size = vec.size();
	if (size == 0)
		throw domain_error("median of an empty vector");
	sort(vec.begin(), vec.end());
	vec_sz mid = size / 2;
	return size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
}


//student_info.h

#pragma once
//student_info.h
#include 
#include 
#include 
using std::vector;
using std::string;
struct student_info{
	string name;
	double midterm, final;
	vectorhomework;
};
bool cmp(const student_info&, const student_info&);
std::istream& read(std::istream&, student_info&);
std::istream&read_hw(std::istream&, std::vector&);
bool cmp(const student_info& x, const student_info& y)
{
	return x.name < y.name;
}

//从输入流将家庭作业的成绩读入到一个vector中
//这里使用输入流而不直接使用cin的原因是让以后的输入流也可以用其他形式比如文本导入啊什么的...
std::istream& read(std::istream& is, student_info& s)
{
	is >> s.name >> s.midterm >> s.final;
	read_hw(is, s.homework);
	return is;
}

std::istream& read_hw(std::istream& in, vector& hw)
{
	if (in)
	{
		hw.clear();
		double x;
		while (in >> x)
			hw.push_back(x);
		in.clear();//清除输入流中的错误信息
	}
	return in;
}


//grade.h

#pragma once
//grade.h
/*
编写一个头文件grade.h来声明不同的grade重载函数
注意:重载函数最好放到同一个文件里
	  而且,将这些重载函数的声明放在一起会让这些可供选择的函数更容易查找
*/
#include 
#include "median.h"
#include "student_info.h"
using std::vector;
double grade(double, double, double);
double grade(double, double, const vector&);
double grade(const student_info&);

//计算成绩
double grade(double midterm, double final, double homework)
{
	return 0.2*midterm + 0.4*final + 0.4*homework;
}

double grade(double midterm, double final, const vector& hw)
{
	if (hw.size() == 0)
		throw domain_error("student has done no homework");
	return grade(midterm, final, median(hw));
}

double grade(const student_info& s)
{
	return grade(s.midterm, s.final, s.homework);
}


//主程序

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include //setprecision,setw
#include "grade.h"
using std::cin;
using std::cout;
using std::domain_error;
using std::endl;
using std::max;
using std::setprecision;
using std::sort;
using std::streamsize;
using std::string;
using std::vector;
//using namespace std;
int main()
{
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	vector students;
	student_info 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(), cmp);

	//输出姓名和成绩
	for (vector::size_type i = 0; i != students.size(); i++)
	{
		//输出姓名,将姓名填充至maxlen+1个字符的长度
		cout << students[i].name << string(maxlen + 1 - students.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();//异常的话会输出刚才在median.h定义的那句话“median of an empty vector”
		}
		cout << endl;
	}

	fclose(stdin);
	fclose(stdout);
	system("pause");
	return 0;
}


C++第二次作业(Accelerated C++第四章)_第4张图片




(五)异常处理

题意描述:练习3-6

首先描述在你的系统在程序运行中出现除以0的情况时如何反应;然后在3.1节的程序中添加C++的异常处理,使得程序行为不依赖于系统如何对待除以0的情况,亦即你的程序不論在何種系統中運行當遇到除以0的情況都會以同樣的方式予以處理。



什么都不做,编译器显示  -nan(ind)

/*
直接除以0的反应,直接显示“被零除或对零求模”
在3.1节中添加异常处理
使得你的程序不论在何种系统中运行当遇到除以0的情况都会以同样的方式处理
*/
#include 
#include 
#include //setw,setprecision
#include 
#include 
#include 
#include //domain_error
using namespace std;

int main()
{
	// ask for and read the student's name
	cout << "Please enter your first name: ";
	string name;
	cin >> name;
	cout << "Hello, " << name << "!" << endl;

	// ask for and read the midterm and final grades
	cout << "Please enter your midterm and final exam grades: ";
	double midterm, final;
	cin >> midterm >> final;

	// ask for the homework grades
	cout << "Enter all your homework grades, "
		"followed by end-of-file: ";

	// the number and sum of grades read so far
	int count = 0;
	double sum = 0;

	// a variable into which to read
	double x;

	// invariant:
	//     we have read `count' grades so far, and
	//     `sum' is the sum of the first `count' grades
	while (cin >> x) {
		++count;
		sum += x;
	}

	// write the result
	try {
		streamsize prec = cout.precision();
		if (count == 0)
			throw domain_error("错了,不能放0在分母\n");
		cout << "Your final grade is " << setprecision(3)
			<< 0.2 * midterm + 0.4 * final + 0.4 * sum / count
			<< setprecision(prec) << endl;
	}
	catch (domain_error e) {
		cout << e.what();
	}
	//catch (domain_error) {
	//	cout << "除以0了,出错了" << endl;
	//}
	system("pause");
	return 0;
}


这样改,然后如果分母用0了,就是抛出异常,然后输出的话是throw domain_error("")里面写的字

catch (domain_error e) {
		cout << e.what();
	}
catch (domain_error) {
		cout << "除以0了,出错了" << endl;
	}
上面这两种用法都可以。

注意:要使用异常抛出需要添加头文件



你可能感兴趣的:(C/C++)